bmv

Batch file moving utilities
git clone git://jacobedwards.org/bmv
Log | Files | Refs | README

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 }