buf.c (2206B)
1 /* 2 * Copyright 2021, 2022 Jacob R. Edwards 3 * 4 * ap -- audio player 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20 /* 21 * This was copied from the aps project on 2023-04-08 22 * The bufword, bufline, and bufgetline functions were 23 * removed as they wouldn't ever find purpose here. 24 */ 25 26 #include <errno.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <stdint.h> 30 #include <ctype.h> 31 32 #include "buf.h" 33 34 struct buf * 35 bufnew(void) 36 { 37 return calloc(1, sizeof(struct buf)); 38 } 39 40 void 41 buffree(struct buf *buf) 42 { 43 if (buf == NULL) 44 return; 45 free(buf->data); 46 free(buf); 47 } 48 49 int 50 bufresize(struct buf *buf, size_t newsize) 51 { 52 char *tmp; 53 54 if (buf == NULL || newsize < buf->len) { 55 errno = EINVAL; 56 return 1; 57 } 58 59 tmp = realloc(buf->data, newsize); 60 if (tmp == NULL) 61 return 1; 62 63 buf->data = tmp; 64 buf->size = newsize; 65 return 0; 66 } 67 68 int 69 bufenlarge(struct buf *buf, size_t needed) 70 { 71 size_t newsize; 72 73 for (newsize = buf->size ? buf->size : (1024 * 8); 74 newsize != SIZE_MAX && needed > (newsize - buf->len);) { 75 if (newsize > SIZE_MAX / 4) 76 newsize = SIZE_MAX; 77 else 78 newsize *= 4; 79 } 80 81 if (needed > (newsize - buf->len)) { 82 errno = EOVERFLOW; 83 return 1; 84 } 85 if (newsize == buf->size) 86 return 0; 87 return bufresize(buf, newsize); 88 } 89 90 int 91 bufappend(struct buf *buf, void *data, size_t len) 92 { 93 if (buf == NULL || bufenlarge(buf, len)) 94 return 1; 95 memcpy(buf->data + buf->len, data, len); 96 buf->len += len; 97 return 0; 98 } 99 100 int 101 bufshift(struct buf *buf, size_t n) 102 { 103 if (n > buf->len) { 104 errno = EOVERFLOW; 105 return 1; 106 } 107 memmove(buf->data, buf->data + n, buf->len - n); 108 buf->len -= n; 109 return 0; 110 }