| 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 | */ |