BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file SimpleStreamBuffer.c
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29  
30 #include <string.h>
31 #include <stddef.h>
32  
33 #include <misc/balloc.h>
34 #include <misc/minmax.h>
35  
36 #include "SimpleStreamBuffer.h"
37  
38 static void try_output (SimpleStreamBuffer *o)
39 {
40 ASSERT(o->output_data_len > 0)
41  
42 // calculate number of bytes to output
43 int bytes = bmin_int(o->output_data_len, o->buf_used);
44 if (bytes == 0) {
45 return;
46 }
47  
48 // copy bytes to output
49 memcpy(o->output_data, o->buf, bytes);
50  
51 // shift buffer
52 memmove(o->buf, o->buf + bytes, o->buf_used - bytes);
53 o->buf_used -= bytes;
54  
55 // forget data
56 o->output_data_len = -1;
57  
58 // done
59 StreamRecvInterface_Done(&o->output, bytes);
60 }
61  
62 static void output_handler_recv (SimpleStreamBuffer *o, uint8_t *data, int data_len)
63 {
64 DebugObject_Access(&o->d_obj);
65 ASSERT(o->output_data_len == -1)
66 ASSERT(data)
67 ASSERT(data_len > 0)
68  
69 // remember data
70 o->output_data = data;
71 o->output_data_len = data_len;
72  
73 try_output(o);
74 }
75  
76 int SimpleStreamBuffer_Init (SimpleStreamBuffer *o, int buf_size, BPendingGroup *pg)
77 {
78 ASSERT(buf_size > 0)
79  
80 // init arguments
81 o->buf_size = buf_size;
82  
83 // init output
84 StreamRecvInterface_Init(&o->output, (StreamRecvInterface_handler_recv)output_handler_recv, o, pg);
85  
86 // allocate buffer
87 if (!(o->buf = (uint8_t *)BAlloc(buf_size))) {
88 goto fail1;
89 }
90  
91 // init buffer state
92 o->buf_used = 0;
93  
94 // set no output data
95 o->output_data_len = -1;
96  
97 DebugObject_Init(&o->d_obj);
98 return 1;
99  
100 fail1:
101 StreamRecvInterface_Free(&o->output);
102 return 0;
103 }
104  
105 void SimpleStreamBuffer_Free (SimpleStreamBuffer *o)
106 {
107 DebugObject_Free(&o->d_obj);
108  
109 // free buffer
110 BFree(o->buf);
111  
112 // free output
113 StreamRecvInterface_Free(&o->output);
114 }
115  
116 StreamRecvInterface * SimpleStreamBuffer_GetOutput (SimpleStreamBuffer *o)
117 {
118 DebugObject_Access(&o->d_obj);
119  
120 return &o->output;
121 }
122  
123 int SimpleStreamBuffer_Write (SimpleStreamBuffer *o, uint8_t *data, int data_len)
124 {
125 DebugObject_Access(&o->d_obj);
126 ASSERT(data_len >= 0)
127  
128 if (data_len > o->buf_size - o->buf_used) {
129 return 0;
130 }
131  
132 // copy to buffer
133 memcpy(o->buf + o->buf_used, data, data_len);
134  
135 // update buffer state
136 o->buf_used += data_len;
137  
138 // continue outputting
139 if (o->output_data_len > 0) {
140 try_output(o);
141 }
142  
143 return 1;
144 }