1 /* 2 * buffer.c 3 * dynamically-managed buffers 4 * 5 * Copyright (c) 2024 pkgconf authors (see AUTHORS). 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * This software is provided 'as is' and without any warranty, express or 12 * implied. In no event shall the authors be liable for any damages arising 13 * from the use of this software. 14 */ 15 16 #include <libpkgconf/stdinc.h> 17 #include <libpkgconf/libpkgconf.h> 18 19 /* 20 * !doc 21 * 22 * libpkgconf `buffer` module 23 * ========================== 24 * 25 * The libpkgconf `buffer` module contains the functions related to managing 26 * dynamically-allocated buffers. 27 */ 28 29 static inline size_t 30 target_allocation_size(size_t target_size) 31 { 32 return 4096 + (4096 * (target_size / 4096)); 33 } 34 35 void 36 pkgconf_buffer_append(pkgconf_buffer_t *buffer, const char *text) 37 { 38 size_t needed = strlen(text) + 1; 39 size_t newsize = pkgconf_buffer_len(buffer) + needed; 40 41 char *newbase = realloc(buffer->base, target_allocation_size(newsize)); 42 43 /* XXX: silently failing here is antisocial */ 44 if (newbase == NULL) 45 return; 46 47 char *newend = newbase + pkgconf_buffer_len(buffer); 48 pkgconf_strlcpy(newend, text, needed); 49 50 buffer->base = newbase; 51 buffer->end = newend + needed; 52 } 53 54 void 55 pkgconf_buffer_push_byte(pkgconf_buffer_t *buffer, char byte) 56 { 57 size_t newsize = pkgconf_buffer_len(buffer) + 1; 58 char *newbase = realloc(buffer->base, target_allocation_size(newsize)); 59 60 /* XXX: silently failing here remains antisocial */ 61 if (newbase == NULL) 62 return; 63 64 char *newend = newbase + newsize; 65 *(newend - 1) = byte; 66 *newend = '\0'; 67 68 buffer->base = newbase; 69 buffer->end = newend; 70 } 71 72 void 73 pkgconf_buffer_trim_byte(pkgconf_buffer_t *buffer) 74 { 75 size_t newsize = pkgconf_buffer_len(buffer) - 1; 76 char *newbase = realloc(buffer->base, target_allocation_size(newsize)); 77 78 buffer->base = newbase; 79 buffer->end = newbase + newsize; 80 *(buffer->end) = '\0'; 81 } 82 83 void 84 pkgconf_buffer_finalize(pkgconf_buffer_t *buffer) 85 { 86 free(buffer->base); 87 } 88