From 2790944b69e858e3a3c45d9d8857090f77e1a74c Mon Sep 17 00:00:00 2001 From: Dan Egnor <egnor@ofb.net> Date: Sun, 26 Nov 2000 18:41:41 +0000 Subject: [PATCH] add Ians read work --- Makefile.am | 2 +- test-oop.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index c70902a..d707d93 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,7 +12,7 @@ INCLUDES = $(GLIB_INCLUDES) $(WWW_INCLUDES) # versions updated as of 0.7 liboop_la_LDFLAGS = -version-info 3:0:0 # version:revision:age -liboop_la_SOURCES = sys.c select.c signal.c alloc.c +liboop_la_SOURCES = sys.c select.c signal.c alloc.c read.c read-fd.c read-mem.c liboop_adns_la_LDFLAGS = -version-info 1:0:1 liboop_adns_la_SOURCES = adns.c diff --git a/test-oop.c b/test-oop.c index b6e16ab..d882f20 100644 --- a/test-oop.c +++ b/test-oop.c @@ -9,11 +9,15 @@ #include <signal.h> #include <stdlib.h> #include <unistd.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> #include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h> #include "oop.h" +#include "oop-read.h" #ifdef HAVE_GLIB #include <glib.h> @@ -54,6 +58,11 @@ static void usage(void) { #ifdef HAVE_WWW " libwww some HTTP GET operations\n" #endif +" read:<delim-spec><nul-mode><shortrec-mode>[<maxrecsz>][,<bufsz>][:<data>]\n" +" <delim-spec>: n | s<delim> | k<delim>\n" +" <delim>: =<char> | n | <hex><hex>\n" +" <nul-mode>: f | d | p\n" +" <shortrec-mode>: f | e | l | s\n" ,stderr); exit(1); } @@ -331,6 +340,158 @@ static void add_www(oop_source *source) { #endif +typedef void on_read_err_func(oop_source*,oop_read*); + +static void *on_read(oop_source *source, oop_read *rd, + oop_rd_event event, const char *errmsg, int errnoval, + const char *data, size_t recsz, void *next_v) { + on_read_err_func **next= next_v; + size_t off; + int c; + + printf("read %s %s%s%s%s %s ", + next ? "error" : "ok", + + event == OOP_RD_OK ? "OK" : + event == OOP_RD_EOF ? "EOF" : + event == OOP_RD_PARTREC ? "PARTREC" : + event == OOP_RD_LONG ? "LONG" : + event == OOP_RD_NUL ? "NUL" : + event == OOP_RD_SYSTEM ? "SYSTEM" : + (assert(!"event must be valid"), (char*)0), + + errmsg?" `":"", errmsg?errmsg:"", errmsg?"'":"", + errnoval ? strerror(errnoval) : "Zero"); + + if (data) { + + printf("%lu:\"", (unsigned long)recsz); + + for (off=0; off<recsz; off++) { + c = (unsigned char)data[off]; + if (c==' ' || (isprint(c) && !isspace(c))) { + putchar(c); + } else { + switch (c) { + case '\n': fputs("\\n",stdout); break; + case '\t': fputs("\\t",stdout); break; + default: printf("\\x%02x",c); + } + } + } + + assert(!data[recsz]); + + putchar('"'); + + } else { + fputs("null",stdout); + } + + putchar('\n'); + + if (next) + (*next)(source,rd); + + return OOP_CONTINUE; +} + +static void *stop_read(oop_source *src,int sig,void *rd_v) { + oop_read *rd= rd_v; + + src->cancel_signal(src,SIGQUIT,stop_read,rd); + oop_rd_delete_tidy(rd); + return OOP_CONTINUE; +} + +static void on_read_immed_err(oop_source *src, oop_read *rd) { + puts("read: terminating"); + stop_read(src,0,rd); +} + +static void on_read_std_err(oop_source *src, oop_read *rd) { + static on_read_err_func *const next= on_read_immed_err; + int r; + + puts("read: switching to plain immediate mode"); + r= oop_rd_read(rd,OOP_RD_STYLE_IMMED,0, on_read,0, on_read,(void*)&next); + if (r) { perror("oop_rd_read[2]"); exit(1); } +} + +static void read_bad(const char *errmsg) { + fprintf(stderr,"invalid modes for read:...: %s\n",errmsg); + usage(); +} + +static void add_read(oop_source *source, const char *modes) { + static on_read_err_func *const next= on_read_std_err; + + oop_readable *ra; + oop_read *rd; + oop_rd_style style; + size_t bufsz, maxrecsz; + int r; + char delimspec[3]; + char *ep; + + switch (*modes++) { + case 'n': style.delim_mode= OOP_RD_DELIM_NONE; break; + case 's': style.delim_mode= OOP_RD_DELIM_STRIP; break; + case 'k': style.delim_mode= OOP_RD_DELIM_KEEP; break; + default: read_bad("invalid delim_mode, must be one of nsk"); + } + if (style.delim_mode != OOP_RD_DELIM_NONE) { + switch ((delimspec[0] = *modes++)) { + case '=': style.delim= *modes++; break; + case 'n': style.delim= '\n'; break; + case '\0': read_bad("missing delimiter"); + default: + delimspec[1]= *modes++; + delimspec[2]= 0; + style.delim= strtoul(delimspec,&ep,16); + if (ep != modes) read_bad("invalid delimiter"); + } + } + + switch (*modes++) { + case 'f': style.nul_mode= OOP_RD_NUL_FORBID; break; + case 'd': style.nul_mode= OOP_RD_NUL_DISCARD; break; + case 'p': style.nul_mode= OOP_RD_NUL_PERMIT; break; + default: read_bad("invalid nul_mode, must be one of fdp"); + } + + switch (*modes++) { + case 'f': style.shortrec_mode= OOP_RD_SHORTREC_FORBID; break; + case 'e': style.shortrec_mode= OOP_RD_SHORTREC_EOF; break; + case 'l': style.shortrec_mode= OOP_RD_SHORTREC_LONG; break; + case 's': style.shortrec_mode= OOP_RD_SHORTREC_SOONEST; break; + default: read_bad("invalid shortrec_mode, must be one of fels"); + } + + maxrecsz= strtoul(modes,&ep,10); + if (*ep && *ep != ',' && *ep != ':') read_bad("invalid maxrecsz"); + modes= *ep==',' ? ep+1 : ep; + + bufsz= strtoul(modes,&ep,10); + if (*ep && *ep != ':') read_bad("invalid bufsz"); + + if (*ep != ':') { + ra= oop_readable_fd(source,0); + if (!ra) { perror("oop_readable_fd"); exit(1); } + } else { + modes= ep+1; + ra= oop_readable_mem(source,modes,strlen(modes)); + if (!ra) { perror("oop_readable_fd"); exit(1); } + } + + rd= oop_rd_new(source,ra, + bufsz ? malloc(bufsz) : 0, + bufsz); + r= oop_rd_read(rd,&style,maxrecsz, on_read,0, on_read,(void*)&next); + if (r) { perror("oop_rd_read"); exit(1); } + source->on_signal(source,SIGQUIT,stop_read,rd); +} + /* -- core ----------------------------------------------------------------- */ static void *stop_loop_delayed(oop_source *source,struct timeval tv,void *x) { @@ -431,6 +592,11 @@ static void add_sink(oop_source *src,const char *name) { return; } + if (!strncmp(name,"read:",5)) { + add_read(src,name+5); + return; + } + fprintf(stderr,"unknown sink \"%s\"\n",name); usage(); } -- GitLab