1 /*
2  * Copyright (c) 2002 2005 Magnus Lind.
3  *
4  * This software is provided 'as-is', without any express or implied warranty.
5  * In no event will the authors be held liable for any damages arising from
6  * the use of this software.
7  *
8  * Permission is granted to anyone to use this software, alter it and re-
9  * distribute it freely for any non-commercial, non-profit purpose subject to
10  * the following restrictions:
11  *
12  *   1. The origin of this software must not be misrepresented; you must not
13  *   claim that you wrote the original software. If you use this software in a
14  *   product, an acknowledgment in the product documentation would be
15  *   appreciated but is not required.
16  *
17  *   2. Altered source versions must be plainly marked as such, and must not
18  *   be misrepresented as being the original software.
19  *
20  *   3. This notice may not be removed or altered from any distribution.
21  *
22  *   4. The names of this software and/or it's copyright holders may not be
23  *   used to endorse or promote products derived from this software without
24  *   specific prior written permission.
25  *
26  */
27 
28 #include "membuf.h"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 
membuf_init(struct membuf * sb)34 void membuf_init(struct membuf *sb)
35 {
36     sb->buf = NULL;
37     sb->len = 0;
38     sb->size = 0;
39 }
membuf_clear(struct membuf * sb)40 void membuf_clear(struct membuf *sb)
41 {
42     sb->len = 0;
43 }
membuf_free(struct membuf * sb)44 void membuf_free(struct membuf *sb)
45 {
46     if (sb->buf != NULL)
47     {
48         free(sb->buf);
49         sb->buf = NULL;
50     }
51     sb->len = 0;
52     sb->size = 0;
53 }
54 
membuf_new(struct membuf ** sbp)55 void membuf_new(struct membuf **sbp)
56 {
57     struct membuf *sb;
58 
59     sb = malloc(sizeof(struct membuf));
60     if (sb == NULL)
61     {
62         fprintf(stderr, "error, can't allocate memory\n");
63         exit(1);
64     }
65 
66     sb->buf = NULL;
67     sb->len = 0;
68     sb->size = 0;
69 
70     *sbp = sb;
71 }
72 
membuf_delete(struct membuf ** sbp)73 void membuf_delete(struct membuf **sbp)
74 {
75     struct membuf *sb;
76 
77     sb = *sbp;
78     membuf_free(sb);
79     free(sb);
80     sb = NULL;
81     *sbp = sb;
82 }
83 
membuf_memlen(struct membuf * sb)84 int membuf_memlen(struct membuf *sb)
85 {
86     return sb->len;
87 }
88 
membuf_truncate(struct membuf * sb,int len)89 void membuf_truncate(struct membuf *sb, int len)
90 {
91     sb->len = len;
92 }
93 
membuf_trim(struct membuf * sb,int pos)94 int membuf_trim(struct membuf *sb, int pos)
95 {
96     if(pos < 0 || pos > sb->len)
97     {
98         return -1;
99     }
100     if(pos == 0)
101     {
102         return sb->len;
103     }
104     if(pos != sb->len)
105     {
106         memmove(sb->buf, (char*)sb->buf + pos, sb->len - pos);
107     }
108     sb->len -= pos;
109     return sb->len;
110 }
111 
membuf_memcpy(struct membuf * sb,const void * mem,int len)112 void *membuf_memcpy(struct membuf *sb, const void *mem, int len)
113 {
114     membuf_atleast(sb, len);
115     memcpy(sb->buf, mem, len);
116     return sb->buf;
117 }
membuf_append(struct membuf * sb,const void * mem,int len)118 void *membuf_append(struct membuf *sb, const void *mem, int len)
119 {
120     int newlen;
121     void *p;
122     newlen = sb->len + len;
123     membuf_atleast(sb, newlen);
124     p = (char *) sb->buf + sb->len;
125     if(mem == NULL)
126     {
127         memset(p, 0, len);
128     }
129     else
130     {
131         memcpy(p, mem, len);
132     }
133     sb->len = newlen;
134     return p;
135 }
136 
membuf_append_char(struct membuf * sb,char c)137 void *membuf_append_char(struct membuf *sb, char c)
138 {
139     int newlen;
140     char *p;
141     newlen = sb->len + 1;
142     membuf_atleast(sb, newlen);
143     p = (char *) sb->buf + sb->len;
144     *p = c;
145     sb->len = newlen;
146     return p;
147 }
148 
membuf_insert(struct membuf * sb,int offset,const void * mem,int len)149 void *membuf_insert(struct membuf *sb, int offset, const void *mem, int len)
150 {
151     int newlen;
152     void *from;
153     void *to;
154     newlen = sb->len + len;
155     membuf_atleast(sb, newlen);
156     from = (char *) sb->buf + offset;
157     to = (char *)from + len;
158     memmove(to, from, sb->len - offset);
159     memcpy(from, mem, len);
160     sb->len = newlen;
161     return from;
162 }
163 
membuf_atleast(struct membuf * sb,int len)164 void membuf_atleast(struct membuf *sb, int len)
165 {
166     int size;
167 
168     size = sb->size;
169     if (size == 0)
170         size = 1;
171     while (size < len)
172     {
173         size <<= 1;
174     }
175     if (size > sb->size)
176     {
177         sb->buf = realloc(sb->buf, size);
178         if (sb->buf == NULL)
179         {
180             fprintf(stderr, "error, can't reallocate memory\n");
181             exit(1);
182         }
183         sb->size = size;
184     }
185 }
186 
membuf_atmost(struct membuf * sb,int len)187 void membuf_atmost(struct membuf *sb, int len)
188 {
189     int size;
190 
191     size = sb->size;
192     while (size > len)
193     {
194         size >>= 1;
195     }
196     if (size < sb->size)
197     {
198         sb->buf = realloc(sb->buf, size);
199         if (sb->buf == NULL)
200         {
201             fprintf(stderr, "error, can't reallocate memory\n");
202             exit(1);
203         }
204         sb->size = size;
205         sb->len = size;
206     }
207 }
208 
membuf_get_size(struct membuf * sb)209 int membuf_get_size(struct membuf *sb)
210 {
211     return sb->size;
212 }
membuf_get(struct membuf * sb)213 void *membuf_get(struct membuf *sb)
214 {
215     return sb->buf;
216 }
217