diff options
Diffstat (limited to 'src/test-bio.c')
-rw-r--r-- | src/test-bio.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/test-bio.c b/src/test-bio.c new file mode 100644 index 0000000..de8dd37 --- /dev/null +++ b/src/test-bio.c @@ -0,0 +1,156 @@ +/* + * test-bio.c - BIO layer for testing + * + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This is a 'source/sink' BIO which supports synthetic inputs and outputs, and + * can be used to drive filter BIOs through a state machine. It buffers all + * output sent to it, which can be retrieved with BIO_test_get_output(), and + * input sent to it, which is handed back in response to BIO_read() by the + * filter BIO. + */ + +#include <assert.h> +#include <string.h> + +#include "src/test-bio.h" +#include "src/util.h" + +int verbose; +int verbose_debug; + +static const unsigned int kMagic = 0x5f8d3f15; + +struct test_ctx +{ + unsigned int magic; + unsigned char *out; + size_t outsz; + unsigned char *in; + size_t insz; +}; + +static struct test_ctx *bio_ctx (BIO *b) +{ + struct test_ctx *ctx = b->ptr; + assert (ctx->magic == kMagic); + return ctx; +} + +static size_t buf_drain (unsigned char **buf, size_t *bufsz, + unsigned char *out, size_t outsz) +{ + if (*bufsz < outsz) + outsz = *bufsz; + memcpy (out, *buf, outsz); + if (*bufsz > outsz) + memmove (*buf, *buf + outsz, *bufsz - outsz); + *bufsz -= outsz; + *buf = realloc (*buf, *bufsz); + return outsz; +} + +static void buf_fill (unsigned char **buf, size_t *bufsz, + const unsigned char *in, size_t insz) +{ + *buf = realloc (*buf, *bufsz + insz); + memcpy (*buf + *bufsz, in, insz); + *bufsz += insz; +} + +int test_new (BIO *b) +{ + struct test_ctx *ctx = malloc (sizeof *ctx); + if (!ctx) + return 0; + ctx->magic = kMagic; + ctx->in = NULL; + ctx->insz = 0; + ctx->out = NULL; + ctx->outsz = 0; + b->init = 1; + b->flags = 0; + b->ptr = ctx; + return 1; +} + +int test_free (BIO *b) +{ + struct test_ctx *ctx; + if (!b || !b->ptr) + return 1; + ctx = bio_ctx (b); + free (ctx->in); + free (ctx->out); + return 1; +} + +int test_write (BIO *b, const char *buf, int sz) +{ + struct test_ctx *ctx = bio_ctx (b); + if (sz <= 0) + return 0; + buf_fill (&ctx->out, &ctx->outsz, (unsigned char *) buf, sz); + return sz; +} + +int test_read (BIO *b, char *buf, int sz) +{ + struct test_ctx *ctx = bio_ctx (b); + if (sz <= 0) + return 0; + return buf_drain (&ctx->in, &ctx->insz, (unsigned char *) buf, sz); +} + +long test_ctrl (BIO *b, int cmd, long num, void *ptr) +{ + return 0; +} + +long test_callback_ctrl (BIO *b, int cmd, bio_info_cb *fp) +{ + return 0; +} + +BIO_METHOD test_methods = +{ + BIO_TYPE_SOCKET, + "test", + test_write, + test_read, + NULL, + NULL, + test_ctrl, + test_new, + test_free, + test_callback_ctrl, +}; + +BIO_METHOD *BIO_s_test() +{ + return &test_methods; +} + +BIO API *BIO_new_test() +{ + return BIO_new (BIO_s_test()); +} + +size_t API BIO_test_output_left (BIO *b) +{ + return bio_ctx (b)->outsz; +} + +size_t API BIO_test_get_output (BIO *b, unsigned char *buf, size_t bufsz) +{ + struct test_ctx *c = bio_ctx (b); + return buf_drain (&c->out, &c->outsz, buf, bufsz); +} + +void API BIO_test_add_input (BIO *b, const unsigned char *buf, size_t bufsz) +{ + struct test_ctx *c = bio_ctx (b); + return buf_fill (&c->in, &c->insz, buf, bufsz); +} |