1/* 2 * libkmod - interface to kernel module operations 3 * 4 * Copyright (C) 2011-2013 ProFUSION embedded systems 5 * Copyright (C) 2014 Intel Corporation. All rights reserved. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#include <assert.h> 22#include <stdbool.h> 23#include <stdlib.h> 24#include <string.h> 25 26#include "util.h" 27#include "strbuf.h" 28 29#define BUF_STEP 128 30 31static bool buf_grow(struct strbuf *buf, size_t newsize) 32{ 33 void *tmp; 34 size_t sz; 35 36 if (newsize <= buf->size) 37 return true; 38 39 if (newsize % BUF_STEP == 0) 40 sz = newsize; 41 else 42 sz = ((newsize / BUF_STEP) + 1) * BUF_STEP; 43 44 tmp = realloc(buf->bytes, sz); 45 if (sz > 0 && tmp == NULL) 46 return false; 47 buf->bytes = tmp; 48 buf->size = sz; 49 return true; 50} 51 52void strbuf_init(struct strbuf *buf) 53{ 54 buf->bytes = NULL; 55 buf->size = 0; 56 buf->used = 0; 57} 58 59void strbuf_release(struct strbuf *buf) 60{ 61 free(buf->bytes); 62} 63 64char *strbuf_steal(struct strbuf *buf) 65{ 66 char *bytes; 67 68 bytes = realloc(buf->bytes, buf->used + 1); 69 if (!bytes) { 70 free(buf->bytes); 71 return NULL; 72 } 73 bytes[buf->used] = '\0'; 74 return bytes; 75} 76 77const char *strbuf_str(struct strbuf *buf) 78{ 79 if (!buf_grow(buf, buf->used + 1)) 80 return NULL; 81 buf->bytes[buf->used] = '\0'; 82 return buf->bytes; 83} 84 85bool strbuf_pushchar(struct strbuf *buf, char ch) 86{ 87 if (!buf_grow(buf, buf->used + 1)) 88 return false; 89 buf->bytes[buf->used] = ch; 90 buf->used++; 91 return true; 92} 93 94unsigned strbuf_pushchars(struct strbuf *buf, const char *str) 95{ 96 unsigned int len; 97 98 assert(str != NULL); 99 assert(buf != NULL); 100 101 len = strlen(str); 102 103 if (!buf_grow(buf, buf->used + len)) 104 return 0; 105 106 memcpy(buf->bytes + buf->used, str, len); 107 buf->used += len; 108 109 return len; 110} 111 112void strbuf_popchar(struct strbuf *buf) 113{ 114 assert(buf->used > 0); 115 buf->used--; 116} 117 118void strbuf_popchars(struct strbuf *buf, unsigned n) 119{ 120 assert(buf->used >= n); 121 buf->used -= n; 122} 123 124void strbuf_clear(struct strbuf *buf) 125{ 126 buf->used = 0; 127} 128 129