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 31 static 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 52 void strbuf_init(struct strbuf *buf) 53 { 54 buf->bytes = NULL; 55 buf->size = 0; 56 buf->used = 0; 57 } 58 59 void strbuf_release(struct strbuf *buf) 60 { 61 free(buf->bytes); 62 } 63 64 char *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 77 const 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 85 bool 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 94 unsigned 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 112 void strbuf_popchar(struct strbuf *buf) 113 { 114 assert(buf->used > 0); 115 buf->used--; 116 } 117 118 void strbuf_popchars(struct strbuf *buf, unsigned n) 119 { 120 assert(buf->used >= n); 121 buf->used -= n; 122 } 123 124 void strbuf_clear(struct strbuf *buf) 125 { 126 buf->used = 0; 127 } 128 129