aboutsummaryrefslogtreecommitdiff
path: root/src/test-bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test-bio.c')
-rw-r--r--src/test-bio.c156
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);
+}