BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file LineBuffer.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 <stdlib.h>
31 #include <string.h>
32  
33 #include <base/BLog.h>
34  
35 #include <flow/LineBuffer.h>
36  
37 #include <generated/blog_channel_LineBuffer.h>
38  
39 static void input_handler_done (LineBuffer *o, int data_len)
40 {
41 DebugObject_Access(&o->d_obj);
42 ASSERT(data_len > 0)
43 ASSERT(data_len <= o->buf_size - o->buf_used)
44  
45 // update buffer
46 o->buf_used += data_len;
47  
48 // look for newline
49 int i;
50 for (i = o->buf_used - data_len; i < o->buf_used; i++) {
51 if (o->buf[i] == o->nl_char) {
52 break;
53 }
54 }
55  
56 if (i < o->buf_used || o->buf_used == o->buf_size) {
57 if (i == o->buf_used) {
58 BLog(BLOG_WARNING, "line too long");
59 }
60  
61 // pass to output
62 o->buf_consumed = (i < o->buf_used ? i + 1 : i);
63 PacketPassInterface_Sender_Send(o->output, o->buf, o->buf_consumed);
64 } else {
65 // receive more data
66 StreamRecvInterface_Receiver_Recv(o->input, o->buf + o->buf_used, o->buf_size - o->buf_used);
67 }
68 }
69  
70 static void output_handler_done (LineBuffer *o)
71 {
72 DebugObject_Access(&o->d_obj);
73 ASSERT(o->buf_consumed > 0)
74 ASSERT(o->buf_consumed <= o->buf_used)
75  
76 // update buffer
77 memmove(o->buf, o->buf + o->buf_consumed, o->buf_used - o->buf_consumed);
78 o->buf_used -= o->buf_consumed;
79  
80 // look for newline
81 int i;
82 for (i = 0; i < o->buf_used; i++) {
83 if (o->buf[i] == o->nl_char) {
84 break;
85 }
86 }
87  
88 if (i < o->buf_used || o->buf_used == o->buf_size) {
89 // pass to output
90 o->buf_consumed = (i < o->buf_used ? i + 1 : i);
91 PacketPassInterface_Sender_Send(o->output, o->buf, o->buf_consumed);
92 } else {
93 // receive more data
94 StreamRecvInterface_Receiver_Recv(o->input, o->buf + o->buf_used, o->buf_size - o->buf_used);
95 }
96 }
97  
98 int LineBuffer_Init (LineBuffer *o, StreamRecvInterface *input, PacketPassInterface *output, int buf_size, uint8_t nl_char)
99 {
100 ASSERT(buf_size > 0)
101 ASSERT(PacketPassInterface_GetMTU(output) >= buf_size)
102  
103 // init arguments
104 o->input = input;
105 o->output = output;
106 o->buf_size = buf_size;
107 o->nl_char = nl_char;
108  
109 // init input
110 StreamRecvInterface_Receiver_Init(o->input, (StreamRecvInterface_handler_done)input_handler_done, o);
111  
112 // init output
113 PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o);
114  
115 // set buffer empty
116 o->buf_used = 0;
117  
118 // allocate buffer
119 if (!(o->buf = (uint8_t *)malloc(o->buf_size))) {
120 BLog(BLOG_ERROR, "malloc failed");
121 goto fail0;
122 }
123  
124 // start receiving
125 StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_size);
126  
127 DebugObject_Init(&o->d_obj);
128 return 1;
129  
130 fail0:
131 return 0;
132 }
133  
134 void LineBuffer_Free (LineBuffer *o)
135 {
136 DebugObject_Free(&o->d_obj);
137  
138 // free buffer
139 free(o->buf);
140 }