Home | History | Annotate | Download | only in shared
      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