9 /* Return every other byte. In particular, reads two bytes, returns
12 every_other_filter (void *opaque, int control,
13 iobuf_t chain, byte *buf, size_t *len)
17 if (control == IOBUFCTRL_DESC)
19 *(char **) buf = "every_other_filter";
21 if (control == IOBUFCTRL_UNDERFLOW)
23 int c = iobuf_readbyte (chain);
28 c2 = iobuf_readbyte (chain);
30 /* printf ("Discarding %d (%c); return %d (%c)\n", c, c, c2, c2); */
48 double_filter (void *opaque, int control,
49 iobuf_t chain, byte *buf, size_t *len)
53 if (control == IOBUFCTRL_DESC)
55 * (char **) buf = "double_filter";
57 if (control == IOBUFCTRL_FLUSH)
61 for (i = 0; i < *len; i ++)
65 rc = iobuf_writebyte (chain, buf[i]);
68 rc = iobuf_writebyte (chain, buf[i]);
77 struct content_filter_state
84 static struct content_filter_state *
85 content_filter_new (const char *buffer)
87 struct content_filter_state *state
88 = malloc (sizeof (struct content_filter_state));
91 state->len = strlen (buffer);
92 state->buffer = buffer;
98 content_filter (void *opaque, int control,
99 iobuf_t chain, byte *buf, size_t *len)
101 struct content_filter_state *state = opaque;
105 if (control == IOBUFCTRL_UNDERFLOW)
107 int remaining = state->len - state->pos;
111 if (toread > remaining)
114 memcpy (buf, &state->buffer[state->pos], toread);
116 state->pos += toread;
129 main (int argc, char *argv[])
134 /* A simple test to make sure filters work. We use a static buffer
135 and then add a filter in front of it that returns every other
138 char *content = "0123456789abcdefghijklm";
144 iobuf = iobuf_temp_with_content (content, strlen (content));
145 rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
149 while ((c = iobuf_readbyte (iobuf)) != -1)
151 /* printf ("%d: %c\n", n + 1, (char) c); */
152 assert (content[2 * n + 1] == c);
155 /* printf ("Got EOF after reading %d bytes (content: %d)\n", */
156 /* n, strlen (content)); */
157 assert (n == strlen (content) / 2);
162 /* A simple test to check buffering. Make sure that when we add a
163 filter to a pipeline, any buffered data gets processed by the */
165 char *content = "0123456789abcdefghijklm";
172 iobuf = iobuf_temp_with_content (content, strlen (content));
175 for (i = 0; i < 10; i ++)
177 c = iobuf_readbyte (iobuf);
178 assert (content[i] == c);
182 rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
185 while ((c = iobuf_readbyte (iobuf)) != -1)
187 /* printf ("%d: %c\n", n + 1, (char) c); */
188 assert (content[2 * (n - 5) + 1] == c);
191 assert (n == 10 + (strlen (content) - 10) / 2);
195 /* A simple test to check that iobuf_read_line works. */
197 /* - 3 characters plus new line
198 - 4 characters plus new line
199 - 5 characters plus new line
200 - 5 characters, no new line
202 char *content = "abc\ndefg\nhijkl\nmnopq";
209 iobuf = iobuf_temp_with_content (content, strlen(content));
211 /* We read a line with 3 characters plus a newline. If we
212 allocate a buffer that is 5 bytes long, then no reallocation
213 should be required. */
215 buffer = malloc (size);
218 n = iobuf_read_line (iobuf, &buffer, &size, &max_len);
220 assert (strcmp (buffer, "abc\n") == 0);
222 assert (max_len == 100);
225 /* We now read a line with 4 characters plus a newline. This
226 requires 6 bytes of storage. We pass a buffer that is 5 bytes
227 large and we allow the buffer to be grown. */
229 buffer = malloc (size);
231 n = iobuf_read_line (iobuf, &buffer, &size, &max_len);
233 assert (strcmp (buffer, "defg\n") == 0);
235 /* The string shouldn't have been truncated (max_len == 0). */
236 assert (max_len == 100);
239 /* We now read a line with 5 characters plus a newline. This
240 requires 7 bytes of storage. We pass a buffer that is 5 bytes
241 large and we don't allow the buffer to be grown. */
243 buffer = malloc (size);
245 n = iobuf_read_line (iobuf, &buffer, &size, &max_len);
247 /* Note: the string should still have a trailing \n. */
248 assert (strcmp (buffer, "hij\n") == 0);
250 /* The string should have been truncated (max_len == 0). */
251 assert (max_len == 0);
254 /* We now read a line with 6 characters without a newline. This
255 requires 7 bytes of storage. We pass a NULL buffer and we
256 don't allow the buffer to be grown larger than 5 bytes. */
260 n = iobuf_read_line (iobuf, &buffer, &size, &max_len);
262 /* Note: the string should still have a trailing \n. */
263 assert (strcmp (buffer, "mno\n") == 0);
265 /* The string should have been truncated (max_len == 0). */
266 assert (max_len == 0);
271 /* - 10 characters, EOF
274 char *content = "abcdefghijklmnopq";
275 char *content2 = "0123456789";
282 iobuf = iobuf_temp_with_content (content, strlen(content));
283 rc = iobuf_push_filter (iobuf,
284 content_filter, content_filter_new (content2));
290 c = iobuf_readbyte (iobuf);
291 if (c == -1 && lastc == -1)
293 /* printf("Two EOFs in a row. Done.\n"); */
302 /* printf("After %d bytes, got EOF.\n", n); */
303 assert (n == 10 || n == 27);
308 /* printf ("%d: '%c' (%d)\n", n, c, c); */
313 /* Write some data to a temporary filter. Push a new filter. The
314 already written data should not be processed by the new
319 char *content = "0123456789";
320 char *content2 = "abc";
324 iobuf = iobuf_temp ();
327 rc = iobuf_write (iobuf, content, strlen (content));
330 rc = iobuf_push_filter (iobuf, double_filter, NULL);
334 rc = iobuf_write (iobuf, content2, strlen (content2) + 1);
337 n = iobuf_temp_to_buffer (iobuf, buffer, sizeof (buffer));
339 printf ("Got %d bytes\n", n);
340 printf ("buffer: `");
341 fwrite (buffer, n, 1, stdout);
342 fputc ('\'', stdout);
343 fputc ('\n', stdout);
346 assert (n == strlen (content) + 2 * (strlen (content2) + 1));
347 assert (strcmp (buffer, "0123456789aabbcc") == 0);
353 char *content = "0123456789";
356 char buffer[strlen (content)];
358 iobuf = iobuf_temp_with_content (content, strlen (content));
361 rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
363 rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
366 for (n = 0; (c = iobuf_get (iobuf)) != -1; n ++)
368 /* printf ("%d: `%c'\n", n, c); */
373 assert (buffer[0] == '3');
374 assert (buffer[1] == '7');