1 /**
2 p_buf.c
3
4
5 Copyright (C) 2003, Network Resonance, Inc.
6 Copyright (C) 2006, Network Resonance, Inc.
7 All Rights Reserved
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 1. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15 2. Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18 3. Neither the name of Network Resonance, Inc. nor the name of any
19 contributors to this software may be used to endorse or promote
20 products derived from this software without specific prior written
21 permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34
35
36 All Rights Reserved.
37
38 ekr@rtfm.com Tue Nov 25 16:33:08 2003
39 */
40
41 static char *RCSSTRING __UNUSED__ ="Id: p_buf.c,v 1.3 2004/01/03 22:13:53 ekr Exp $";
42
43 #include <string.h>
44 #include <stddef.h>
45 #include "nr_common.h"
46 #include "p_buf.h"
47
48
49 static int nr_p_buf_destroy_chain(nr_p_buf_head *head);
50 static int nr_p_buf_destroy(nr_p_buf *buf);
51
nr_p_buf_ctx_create(size,ctxp)52 int nr_p_buf_ctx_create(size,ctxp)
53 int size;
54 nr_p_buf_ctx **ctxp;
55 {
56 int _status;
57 nr_p_buf_ctx *ctx=0;
58
59 if(!(ctx=(nr_p_buf_ctx *)RCALLOC(sizeof(nr_p_buf_ctx))))
60 ABORT(R_NO_MEMORY);
61
62 ctx->buf_size=size;
63 STAILQ_INIT(&ctx->free_list);
64
65 *ctxp=ctx;
66 _status=0;
67 abort:
68 if(_status){
69 nr_p_buf_ctx_destroy(&ctx);
70 }
71 return(_status);
72 }
73
nr_p_buf_ctx_destroy(ctxp)74 int nr_p_buf_ctx_destroy(ctxp)
75 nr_p_buf_ctx **ctxp;
76 {
77 nr_p_buf_ctx *ctx;
78
79 if(!ctxp || !*ctxp)
80 return(0);
81
82 ctx=*ctxp;
83
84 nr_p_buf_destroy_chain(&ctx->free_list);
85
86 RFREE(ctx);
87 *ctxp=0;
88
89 return(0);
90 }
91
nr_p_buf_alloc(ctx,bufp)92 int nr_p_buf_alloc(ctx,bufp)
93 nr_p_buf_ctx *ctx;
94 nr_p_buf **bufp;
95 {
96 int _status;
97 nr_p_buf *buf=0;
98
99 if(!STAILQ_EMPTY(&ctx->free_list)){
100 buf=STAILQ_FIRST(&ctx->free_list);
101 STAILQ_REMOVE_HEAD(&ctx->free_list,entry);
102 goto ok;
103 }
104 else {
105 if(!(buf=(nr_p_buf *)RCALLOC(sizeof(nr_p_buf))))
106 ABORT(R_NO_MEMORY);
107 if(!(buf->data=(UCHAR *)RMALLOC(ctx->buf_size)))
108 ABORT(R_NO_MEMORY);
109 buf->size=ctx->buf_size;
110 }
111
112 ok:
113 buf->r_offset=0;
114 buf->length=0;
115
116 *bufp=buf;
117 _status=0;
118 abort:
119 if(_status){
120 nr_p_buf_destroy(buf);
121 }
122 return(_status);
123 }
124
nr_p_buf_free(ctx,buf)125 int nr_p_buf_free(ctx,buf)
126 nr_p_buf_ctx *ctx;
127 nr_p_buf *buf;
128 {
129 STAILQ_INSERT_TAIL(&ctx->free_list,buf,entry);
130
131 return(0);
132 }
133
nr_p_buf_free_chain(ctx,head)134 int nr_p_buf_free_chain(ctx,head)
135 nr_p_buf_ctx *ctx;
136 nr_p_buf_head *head;
137 {
138 nr_p_buf *n1,*n2;
139
140 n1=STAILQ_FIRST(head);
141 while(n1){
142 n2=STAILQ_NEXT(n1,entry);
143
144 nr_p_buf_free(ctx,n1);
145
146 n1=n2;
147 }
148
149 return(0);
150 }
151
152
nr_p_buf_write_to_chain(ctx,chain,data,len)153 int nr_p_buf_write_to_chain(ctx,chain,data,len)
154 nr_p_buf_ctx *ctx;
155 nr_p_buf_head *chain;
156 UCHAR *data;
157 UINT4 len;
158 {
159 int r,_status;
160 nr_p_buf *buf;
161
162 buf=STAILQ_LAST(chain,nr_p_buf_,entry);
163 while(len){
164 int towrite;
165
166 if(!buf){
167 if(r=nr_p_buf_alloc(ctx,&buf))
168 ABORT(r);
169 STAILQ_INSERT_TAIL(chain,buf,entry);
170 }
171
172 towrite=MIN(len,(buf->size-(buf->length+buf->r_offset)));
173
174 memcpy(buf->data+buf->length+buf->r_offset,data,towrite);
175 len-=towrite;
176 data+=towrite;
177 buf->length+=towrite;
178
179 r_log(LOG_COMMON,LOG_DEBUG,"Wrote %d bytes to buffer %p",towrite,buf);
180 buf=0;
181 }
182
183 _status=0;
184 abort:
185 return(_status);
186 }
187
nr_p_buf_destroy_chain(head)188 static int nr_p_buf_destroy_chain(head)
189 nr_p_buf_head *head;
190 {
191 nr_p_buf *n1,*n2;
192
193 n1=STAILQ_FIRST(head);
194 while(n1){
195 n2=STAILQ_NEXT(n1,entry);
196
197 nr_p_buf_destroy(n1);
198
199 n1=n2;
200 }
201
202 return(0);
203 }
204
nr_p_buf_destroy(buf)205 static int nr_p_buf_destroy(buf)
206 nr_p_buf *buf;
207 {
208 if(!buf)
209 return(0);
210
211 RFREE(buf->data);
212 RFREE(buf);
213
214 return(0);
215 }
216
217
218