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