File: | libs/esl/src/esl_buffer.c |
Location: | line 190, column 2 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* | |||
2 | * Copyright (c) 2010-2012, Anthony Minessale II | |||
3 | * All rights reserved. | |||
4 | * | |||
5 | * Redistribution and use in source and binary forms, with or without | |||
6 | * modification, are permitted provided that the following conditions | |||
7 | * are met: | |||
8 | * | |||
9 | * * Redistributions of source code must retain the above copyright | |||
10 | * notice, this list of conditions and the following disclaimer. | |||
11 | * | |||
12 | * * Redistributions in binary form must reproduce the above copyright | |||
13 | * notice, this list of conditions and the following disclaimer in the | |||
14 | * documentation and/or other materials provided with the distribution. | |||
15 | * | |||
16 | * * Neither the name of the original author; nor the names of any contributors | |||
17 | * may be used to endorse or promote products derived from this software | |||
18 | * without specific prior written permission. | |||
19 | * | |||
20 | * | |||
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | |||
25 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
32 | */ | |||
33 | ||||
34 | ||||
35 | #include "esl_buffer.h" | |||
36 | ||||
37 | static unsigned buffer_id = 0; | |||
38 | ||||
39 | struct esl_buffer { | |||
40 | unsigned char *data; | |||
41 | unsigned char *head; | |||
42 | esl_size_t used; | |||
43 | esl_size_t actually_used; | |||
44 | esl_size_t datalen; | |||
45 | esl_size_t max_len; | |||
46 | esl_size_t blocksize; | |||
47 | unsigned id; | |||
48 | int loops; | |||
49 | }; | |||
50 | ||||
51 | ||||
52 | ESL_DECLARE(esl_status_t)esl_status_t esl_buffer_create(esl_buffer_t **buffer, esl_size_t blocksize, esl_size_t start_len, esl_size_t max_len) | |||
53 | { | |||
54 | esl_buffer_t *new_buffer; | |||
55 | ||||
56 | new_buffer = malloc(sizeof(*new_buffer)); | |||
57 | ||||
58 | if (new_buffer) { | |||
59 | memset(new_buffer, 0, sizeof(*new_buffer)); | |||
60 | ||||
61 | if (start_len) { | |||
62 | new_buffer->data = malloc(start_len); | |||
63 | if (!new_buffer->data) { | |||
64 | free(new_buffer); | |||
65 | return ESL_FAIL; | |||
66 | } | |||
67 | memset(new_buffer->data, 0, start_len); | |||
68 | } | |||
69 | ||||
70 | new_buffer->max_len = max_len; | |||
71 | new_buffer->datalen = start_len; | |||
72 | new_buffer->id = buffer_id++; | |||
73 | new_buffer->blocksize = blocksize; | |||
74 | new_buffer->head = new_buffer->data; | |||
75 | ||||
76 | *buffer = new_buffer; | |||
77 | return ESL_SUCCESS; | |||
78 | } | |||
79 | ||||
80 | return ESL_FAIL; | |||
81 | } | |||
82 | ||||
83 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_len(esl_buffer_t *buffer) | |||
84 | { | |||
85 | ||||
86 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 86, __PRETTY_FUNCTION__)); | |||
87 | ||||
88 | return buffer->datalen; | |||
89 | ||||
90 | } | |||
91 | ||||
92 | ||||
93 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_freespace(esl_buffer_t *buffer) | |||
94 | { | |||
95 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 95, __PRETTY_FUNCTION__)); | |||
96 | ||||
97 | if (buffer->max_len) { | |||
98 | return (esl_size_t) (buffer->max_len - buffer->used); | |||
99 | } | |||
100 | return 1000000; | |||
101 | ||||
102 | } | |||
103 | ||||
104 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_inuse(esl_buffer_t *buffer) | |||
105 | { | |||
106 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 106, __PRETTY_FUNCTION__)); | |||
107 | ||||
108 | return buffer->used; | |||
109 | } | |||
110 | ||||
111 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen) | |||
112 | { | |||
113 | esl_size_t reading = 0; | |||
114 | ||||
115 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 115, __PRETTY_FUNCTION__)); | |||
116 | ||||
117 | if (buffer->used < 1) { | |||
118 | buffer->used = 0; | |||
119 | return 0; | |||
120 | } else if (buffer->used >= datalen) { | |||
121 | reading = datalen; | |||
122 | } else { | |||
123 | reading = buffer->used; | |||
124 | } | |||
125 | ||||
126 | buffer->used = buffer->actually_used - reading; | |||
127 | buffer->head = buffer->data + reading; | |||
128 | ||||
129 | return reading; | |||
130 | } | |||
131 | ||||
132 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen) | |||
133 | { | |||
134 | esl_size_t reading = 0; | |||
135 | ||||
136 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 136, __PRETTY_FUNCTION__)); | |||
137 | ||||
138 | if (buffer->used < 1) { | |||
139 | buffer->used = 0; | |||
140 | return 0; | |||
141 | } else if (buffer->used >= datalen) { | |||
142 | reading = datalen; | |||
143 | } else { | |||
144 | reading = buffer->used; | |||
145 | } | |||
146 | ||||
147 | buffer->used -= reading; | |||
148 | buffer->head += reading; | |||
149 | ||||
150 | return buffer->used; | |||
151 | } | |||
152 | ||||
153 | ESL_DECLARE(void)void esl_buffer_set_loops(esl_buffer_t *buffer, int loops) | |||
154 | { | |||
155 | buffer->loops = loops; | |||
156 | } | |||
157 | ||||
158 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_read_loop(esl_buffer_t *buffer, void *data, esl_size_t datalen) | |||
159 | { | |||
160 | esl_size_t len; | |||
161 | if ((len = esl_buffer_read(buffer, data, datalen)) < datalen) { | |||
162 | if (buffer->loops == 0) { | |||
163 | return len; | |||
164 | } | |||
165 | buffer->head = buffer->data; | |||
166 | buffer->used = buffer->actually_used; | |||
167 | len = esl_buffer_read(buffer, (char*)data + len, datalen - len); | |||
168 | buffer->loops--; | |||
169 | } | |||
170 | return len; | |||
171 | } | |||
172 | ||||
173 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_read(esl_buffer_t *buffer, void *data, esl_size_t datalen) | |||
174 | { | |||
175 | esl_size_t reading = 0; | |||
176 | ||||
177 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 177, __PRETTY_FUNCTION__)); | |||
178 | esl_assert(data != NULL)((data != ((void*)0)) ? (void) (0) : __assert_fail ("data != ((void*)0)" , "libs/esl/src/esl_buffer.c", 178, __PRETTY_FUNCTION__)); | |||
179 | ||||
180 | ||||
181 | if (buffer->used < 1) { | |||
182 | buffer->used = 0; | |||
183 | return 0; | |||
184 | } else if (buffer->used >= datalen) { | |||
185 | reading = datalen; | |||
186 | } else { | |||
187 | reading = buffer->used; | |||
188 | } | |||
189 | ||||
190 | memcpy(data, buffer->head, reading); | |||
| ||||
191 | buffer->used -= reading; | |||
192 | buffer->head += reading; | |||
193 | ||||
194 | /* if (buffer->id == 4) printf("%u o %d = %d\n", buffer->id, (unsigned)reading, (unsigned)buffer->used); */ | |||
195 | return reading; | |||
196 | } | |||
197 | ||||
198 | ||||
199 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_packet_count(esl_buffer_t *buffer) | |||
200 | { | |||
201 | char *pe, *p, *e, *head = (char *) buffer->head; | |||
202 | esl_size_t x = 0; | |||
203 | ||||
204 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 204, __PRETTY_FUNCTION__)); | |||
205 | ||||
206 | e = (head + buffer->used); | |||
207 | ||||
208 | for (p = head; p && *p && p < e; p++) { | |||
209 | if (*p == '\n') { | |||
210 | pe = p+1; | |||
211 | if (*pe == '\r') pe++; | |||
212 | if (pe <= e && *pe == '\n') { | |||
213 | p = pe++; | |||
214 | x++; | |||
215 | } | |||
216 | } | |||
217 | } | |||
218 | ||||
219 | return x; | |||
220 | } | |||
221 | ||||
222 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_read_packet(esl_buffer_t *buffer, void *data, esl_size_t maxlen) | |||
223 | { | |||
224 | char *pe, *p, *e, *head = (char *) buffer->head; | |||
225 | esl_size_t datalen = 0; | |||
226 | ||||
227 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 227, __PRETTY_FUNCTION__)); | |||
228 | esl_assert(data != NULL)((data != ((void*)0)) ? (void) (0) : __assert_fail ("data != ((void*)0)" , "libs/esl/src/esl_buffer.c", 228, __PRETTY_FUNCTION__)); | |||
229 | ||||
230 | e = (head + buffer->used); | |||
231 | ||||
232 | for (p = head; p && *p && p < e; p++) { | |||
| ||||
233 | if (*p == '\n') { | |||
234 | pe = p+1; | |||
235 | if (*pe == '\r') pe++; | |||
236 | if (pe <= e && *pe == '\n') { | |||
237 | pe++; | |||
238 | datalen = pe - head; | |||
239 | if (datalen > maxlen) { | |||
240 | datalen = maxlen; | |||
241 | } | |||
242 | break; | |||
243 | } | |||
244 | } | |||
245 | } | |||
246 | ||||
247 | return esl_buffer_read(buffer, data, datalen); | |||
248 | } | |||
249 | ||||
250 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen) | |||
251 | { | |||
252 | esl_size_t freespace, actual_freespace; | |||
253 | ||||
254 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 254, __PRETTY_FUNCTION__)); | |||
255 | esl_assert(data != NULL)((data != ((void*)0)) ? (void) (0) : __assert_fail ("data != ((void*)0)" , "libs/esl/src/esl_buffer.c", 255, __PRETTY_FUNCTION__)); | |||
256 | esl_assert(buffer->data != NULL)((buffer->data != ((void*)0)) ? (void) (0) : __assert_fail ("buffer->data != ((void*)0)", "libs/esl/src/esl_buffer.c" , 256, __PRETTY_FUNCTION__)); | |||
257 | ||||
258 | if (!datalen) { | |||
259 | return buffer->used; | |||
260 | } | |||
261 | ||||
262 | actual_freespace = buffer->datalen - buffer->actually_used; | |||
263 | if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) { | |||
264 | memmove(buffer->data, buffer->head, buffer->used); | |||
265 | buffer->head = buffer->data; | |||
266 | buffer->actually_used = buffer->used; | |||
267 | } | |||
268 | ||||
269 | freespace = buffer->datalen - buffer->used; | |||
270 | ||||
271 | /* | |||
272 | if (buffer->data != buffer->head) { | |||
273 | memmove(buffer->data, buffer->head, buffer->used); | |||
274 | buffer->head = buffer->data; | |||
275 | } | |||
276 | */ | |||
277 | ||||
278 | if (freespace < datalen) { | |||
279 | esl_size_t new_size, new_block_size; | |||
280 | void *data1; | |||
281 | ||||
282 | new_size = buffer->datalen + datalen; | |||
283 | new_block_size = buffer->datalen + buffer->blocksize; | |||
284 | ||||
285 | if (new_block_size > new_size) { | |||
286 | new_size = new_block_size; | |||
287 | } | |||
288 | buffer->head = buffer->data; | |||
289 | data1 = realloc(buffer->data, new_size); | |||
290 | if (!data1) { | |||
291 | return 0; | |||
292 | } | |||
293 | buffer->data = data1; | |||
294 | buffer->head = buffer->data; | |||
295 | buffer->datalen = new_size; | |||
296 | } | |||
297 | ||||
298 | ||||
299 | freespace = buffer->datalen - buffer->used; | |||
300 | ||||
301 | if (freespace < datalen) { | |||
302 | return 0; | |||
303 | } else { | |||
304 | memcpy(buffer->head + buffer->used, data, datalen); | |||
305 | buffer->used += datalen; | |||
306 | buffer->actually_used += datalen; | |||
307 | } | |||
308 | /* if (buffer->id == 4) printf("%u i %d = %d\n", buffer->id, (unsigned)datalen, (unsigned)buffer->used); */ | |||
309 | ||||
310 | return buffer->used; | |||
311 | } | |||
312 | ||||
313 | ESL_DECLARE(void)void esl_buffer_zero(esl_buffer_t *buffer) | |||
314 | { | |||
315 | esl_assert(buffer != NULL)((buffer != ((void*)0)) ? (void) (0) : __assert_fail ("buffer != ((void*)0)" , "libs/esl/src/esl_buffer.c", 315, __PRETTY_FUNCTION__)); | |||
316 | esl_assert(buffer->data != NULL)((buffer->data != ((void*)0)) ? (void) (0) : __assert_fail ("buffer->data != ((void*)0)", "libs/esl/src/esl_buffer.c" , 316, __PRETTY_FUNCTION__)); | |||
317 | ||||
318 | buffer->used = 0; | |||
319 | buffer->actually_used = 0; | |||
320 | buffer->head = buffer->data; | |||
321 | } | |||
322 | ||||
323 | ESL_DECLARE(esl_size_t)esl_size_t esl_buffer_zwrite(esl_buffer_t *buffer, const void *data, esl_size_t datalen) | |||
324 | { | |||
325 | esl_size_t w; | |||
326 | ||||
327 | if (!(w = esl_buffer_write(buffer, data, datalen))) { | |||
328 | esl_buffer_zero(buffer); | |||
329 | return esl_buffer_write(buffer, data, datalen); | |||
330 | } | |||
331 | ||||
332 | return w; | |||
333 | } | |||
334 | ||||
335 | ESL_DECLARE(void)void esl_buffer_destroy(esl_buffer_t **buffer) | |||
336 | { | |||
337 | if (*buffer) { | |||
338 | free((*buffer)->data); | |||
339 | (*buffer)->data = NULL((void*)0); | |||
340 | free(*buffer); | |||
341 | } | |||
342 | ||||
343 | *buffer = NULL((void*)0); | |||
344 | } | |||
345 | ||||
346 | /* For Emacs: | |||
347 | * Local Variables: | |||
348 | * mode:c | |||
349 | * indent-tabs-mode:t | |||
350 | * tab-width:4 | |||
351 | * c-basic-offset:4 | |||
352 | * End: | |||
353 | * For VIM: | |||
354 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: | |||
355 | */ |