Index: ossp-pkg/l2/l2_ch_buffer.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ch_buffer.c,v rcsdiff -q -kk '-r1.7' '-r1.8' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ch_buffer.c,v' 2>/dev/null --- l2_ch_buffer.c 2001/08/23 05:30:58 1.7 +++ l2_ch_buffer.c 2001/08/24 15:16:43 1.8 @@ -32,33 +32,45 @@ #include +/* declare private channel configuration */ typedef struct { char *buf; int bufpos; int bufsize; } l2_ch_buffer_t; +/* create channel */ static int hook_create(l2_context_t *ctx) { l2_ch_buffer_t *cfg; + /* allocate private channel configuration */ if ((cfg = (l2_ch_buffer_t *)malloc(sizeof(l2_ch_buffer_t))) == NULL) return L2_ERROR; + + /* initialize configuration with reasonable defaults */ cfg->buf = NULL; cfg->bufpos = 0; cfg->bufsize = 4096; + + /* link private channel configuration into channel context */ ctx->vp = cfg; + return L2_OK; } +/* configure channel */ static int hook_configure(l2_context_t *ctx, const char *fmt, va_list ap) { l2_ch_buffer_t *cfg; l2_param_t pa[3]; l2_result_t rv; + /* parameter checks */ if ((cfg = (l2_ch_buffer_t *)ctx->vp) == NULL) return L2_ERROR; + + /* feed and call generic parameter parsing engine */ L2_PARAM_SET(pa[0], size, INT, &cfg->bufsize); L2_PARAM_END(pa[2]); rv = l2_channel_setparams(pa, fmt, ap); @@ -67,89 +79,119 @@ return rv; } +/* open channel */ static int hook_open(l2_context_t *ctx, l2_channel_t *downstream) { l2_ch_buffer_t *cfg; + /* parameter checks */ if ((cfg = (l2_ch_buffer_t *)ctx->vp) == NULL) return L2_ERROR; + + /* open channel buffer */ if (cfg->bufsize > 0) { if ((cfg->buf = malloc(cfg->bufsize)) == NULL) return L2_ERROR; cfg->bufpos = 0; } + + /* optionally open downstream channel, too */ if (downstream != NULL) if (l2_channel_open(downstream) == L2_ERROR) return L2_ERROR; + return L2_OK; } +/* write to channel */ static int hook_write(l2_context_t *ctx, l2_channel_t *downstream, const char *buf, size_t bufsize) { l2_ch_buffer_t *cfg; + /* parameter checks */ if ((cfg = (l2_ch_buffer_t *)ctx->vp) == NULL) return L2_ERROR; - if (bufsize > (cfg->bufsize - cfg->bufpos)) return L2_ERROR; /* The buffer is too small */ + /* write message to channel buffer */ memcpy(cfg->buf+cfg->bufpos, buf, bufsize); cfg->bufpos += bufsize; return L2_OK; } +/* flush channel */ static int hook_flush(l2_context_t *ctx, l2_channel_t *downstream) { l2_ch_buffer_t *cfg; + /* parameter checks */ if ((cfg = (l2_ch_buffer_t *)ctx->vp) == NULL) return L2_ERROR; + /* write the buffer contents downstream */ if (cfg->bufpos > 0) { if (downstream != NULL) if (l2_channel_write(downstream, cfg->buf, cfg->bufpos) == L2_ERROR) return L2_ERROR; cfg->bufpos = 0; - memset(cfg->buf, 0x5A, cfg->bufsize); /* Guard against improper usage */ } + /* optionally flush downstream channel, too */ if (downstream != NULL) if (l2_channel_flush(downstream) == L2_ERROR) return L2_ERROR; + return L2_OK; } +/* close channel */ static int hook_close(l2_context_t *ctx, l2_channel_t *downstream) { l2_ch_buffer_t *cfg; + /* optionally close downstream channel, too */ if (downstream != NULL) if (l2_channel_close(downstream) == L2_ERROR) return L2_ERROR; + + /* parameter checks */ if ((cfg = (l2_ch_buffer_t *)ctx->vp) == NULL) return L2_ERROR; + + /* close channel buffer */ if (cfg->buf != NULL) { free(cfg->buf); cfg->buf = NULL; } + return L2_OK; } +/* destroy channel */ static int hook_destroy(l2_context_t *ctx) { l2_ch_buffer_t *cfg; + /* parameter checks */ if ((cfg = (l2_ch_buffer_t *)ctx->vp) == NULL) return L2_ERROR; - if (cfg->buf != NULL) + + /* if not already closed, close channel buffer now */ + if (cfg->buf != NULL) { free(cfg->buf); + cfg->buf = NULL; + } + + /* destroy channel configuration */ free(cfg); + return L2_OK; } +/* exported channel handler structure */ l2_handler_t l2_handler_buffer = { hook_create, hook_configure,