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