• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * test-bio.c - BIO layer for testing
3  *
4  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  *
8  * This is a 'source/sink' BIO which supports synthetic inputs and outputs, and
9  * can be used to drive filter BIOs through a state machine. It buffers all
10  * output sent to it, which can be retrieved with BIO_test_get_output(), and
11  * input sent to it, which is handed back in response to BIO_read() by the
12  * filter BIO.
13  */
14 
15 #include <assert.h>
16 #include <string.h>
17 
18 #include "src/test-bio.h"
19 #include "src/util.h"
20 
21 int verbose;
22 int verbose_debug;
23 
24 static const unsigned int kMagic = 0x5f8d3f15;
25 
26 struct test_ctx
27 {
28   unsigned int magic;
29   unsigned char *out;
30   size_t outsz;
31   unsigned char *in;
32   size_t insz;
33 };
34 
bio_ctx(BIO * b)35 static struct test_ctx *bio_ctx (BIO *b)
36 {
37   struct test_ctx *ctx = b->ptr;
38   assert (ctx->magic == kMagic);
39   return ctx;
40 }
41 
buf_drain(unsigned char ** buf,size_t * bufsz,unsigned char * out,size_t outsz)42 static size_t buf_drain (unsigned char **buf, size_t *bufsz,
43                          unsigned char *out, size_t outsz)
44 {
45   if (*bufsz < outsz)
46     outsz = *bufsz;
47   memcpy (out, *buf, outsz);
48   if (*bufsz > outsz)
49     memmove (*buf, *buf + outsz, *bufsz - outsz);
50   *bufsz -= outsz;
51   *buf = realloc (*buf, *bufsz);
52   return outsz;
53 }
54 
buf_fill(unsigned char ** buf,size_t * bufsz,const unsigned char * in,size_t insz)55 static void buf_fill (unsigned char **buf, size_t *bufsz,
56                       const unsigned char *in, size_t insz)
57 {
58   *buf = realloc (*buf, *bufsz + insz);
59   memcpy (*buf + *bufsz, in, insz);
60   *bufsz += insz;
61 }
62 
test_new(BIO * b)63 int test_new (BIO *b)
64 {
65   struct test_ctx *ctx = malloc (sizeof *ctx);
66   if (!ctx)
67     return 0;
68   ctx->magic = kMagic;
69   ctx->in = NULL;
70   ctx->insz = 0;
71   ctx->out = NULL;
72   ctx->outsz = 0;
73   b->init = 1;
74   b->flags = 0;
75   b->ptr = ctx;
76   return 1;
77 }
78 
test_free(BIO * b)79 int test_free (BIO *b)
80 {
81   struct test_ctx *ctx;
82   if (!b || !b->ptr)
83     return 1;
84   ctx = bio_ctx (b);
85   free (ctx->in);
86   free (ctx->out);
87   return 1;
88 }
89 
test_write(BIO * b,const char * buf,int sz)90 int test_write (BIO *b, const char *buf, int sz)
91 {
92   struct test_ctx *ctx = bio_ctx (b);
93   if (sz <= 0)
94     return 0;
95   buf_fill (&ctx->out, &ctx->outsz, (unsigned char *) buf, sz);
96   return sz;
97 }
98 
test_read(BIO * b,char * buf,int sz)99 int test_read (BIO *b, char *buf, int sz)
100 {
101   struct test_ctx *ctx = bio_ctx (b);
102   if (sz <= 0)
103     return 0;
104   return buf_drain (&ctx->in, &ctx->insz, (unsigned char *) buf, sz);
105 }
106 
test_ctrl(BIO * b,int cmd,long num,void * ptr)107 long test_ctrl (BIO *b, int cmd, long num, void *ptr)
108 {
109   return 0;
110 }
111 
test_callback_ctrl(BIO * b,int cmd,bio_info_cb fp)112 long test_callback_ctrl (BIO *b, int cmd, bio_info_cb fp)
113 {
114   return 0;
115 }
116 
117 BIO_METHOD test_methods =
118 {
119   BIO_TYPE_SOCKET,
120   "test",
121   test_write,
122   test_read,
123   NULL,
124   NULL,
125   test_ctrl,
126   test_new,
127   test_free,
128   test_callback_ctrl,
129 };
130 
BIO_s_test()131 BIO_METHOD *BIO_s_test()
132 {
133   return &test_methods;
134 }
135 
BIO_new_test()136 BIO API *BIO_new_test()
137 {
138   return BIO_new (BIO_s_test());
139 }
140 
BIO_test_output_left(BIO * b)141 size_t API BIO_test_output_left (BIO *b)
142 {
143   return bio_ctx (b)->outsz;
144 }
145 
BIO_test_get_output(BIO * b,unsigned char * buf,size_t bufsz)146 size_t API BIO_test_get_output (BIO *b, unsigned char *buf, size_t bufsz)
147 {
148   struct test_ctx *c = bio_ctx (b);
149   return buf_drain (&c->out, &c->outsz, buf, bufsz);
150 }
151 
BIO_test_add_input(BIO * b,const unsigned char * buf,size_t bufsz)152 void API BIO_test_add_input (BIO *b, const unsigned char *buf, size_t bufsz)
153 {
154   struct test_ctx *c = bio_ctx (b);
155   return buf_fill (&c->in, &c->insz, buf, bufsz);
156 }
157