comparison src/dmgrowbuf.c @ 1697:1036b0dcccb5

Refactor DMGrowBuf so that there can be buffers that grow "backwards". This also removes some support functions like the buffer state push/pop.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 05 Jun 2018 12:55:17 +0300
parents e568535e1a96
children f71cd6691e05
comparison
equal deleted inserted replaced
1696:cf0fddd4bf52 1697:1036b0dcccb5
43 buf->size = initial; 43 buf->size = initial;
44 buf->mingrow = mingrow; 44 buf->mingrow = mingrow;
45 buf->allocated = FALSE; 45 buf->allocated = FALSE;
46 46
47 // Allocate the data 47 // Allocate the data
48 if ((buf->adata = buf->data = dmMalloc0(initial)) == NULL) 48 if ((buf->data = dmMalloc0(initial)) == NULL)
49 return DMERR_MALLOC; 49 return DMERR_MALLOC;
50 50
51 return DMERR_OK; 51 return DMERR_OK;
52 } 52 }
53 53
83 { 83 {
84 DM_DBG("dmGrowBufFree(%p)\n", buf); 84 DM_DBG("dmGrowBufFree(%p)\n", buf);
85 if (buf != NULL) 85 if (buf != NULL)
86 { 86 {
87 DM_DBG( 87 DM_DBG(
88 " buf->adata = %p\n"
89 " buf->data = %p\n" 88 " buf->data = %p\n"
90 " buf->allocated = %s\n", 89 " buf->allocated = %s\n",
91 buf->adata, buf->data, buf->allocated ? "YES" : "NO"); 90 buf->data, buf->allocated ? "YES" : "NO");
92 91
93 dmFreeR(&buf->adata); 92 dmFreeR(&buf->data);
94 buf->data = NULL;
95 93
96 if (buf->allocated) 94 if (buf->allocated)
97 dmFree(buf); 95 dmFree(buf);
98 } 96 }
99 } 97 }
100 98
101 99
102 void dmGrowBufPush(DMGrowBuf *buf)
103 {
104 if (buf != NULL && buf->adata != NULL)
105 {
106 DM_DBG("dmGrowBufPush(%p): size=%" DM_PRIu_SIZE_T "\n"
107 " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n",
108 buf, buf->size, buf->nstack, buf->offs, buf->len);
109
110 buf->stack[buf->nstack].offs = buf->offs;
111 buf->stack[buf->nstack].len = buf->len;
112 buf->nstack++;
113
114 buf->offs = buf->len;
115 buf->data = buf->adata + buf->offs;
116 buf->len = 0;
117
118 DM_DBG(
119 " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n",
120 buf->nstack, buf->offs, buf->len);
121 }
122 else
123 DM_DBG("dmGrowBufPush(%p)\n", buf);
124 }
125
126
127 void dmGrowBufPop(DMGrowBuf *buf)
128 {
129 if (buf != NULL && buf->adata != NULL && buf->nstack > 0)
130 {
131 DM_DBG("dmGrowBufPop(%p): size=%" DM_PRIu_SIZE_T "\n"
132 " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n",
133 buf, buf->size, buf->nstack, buf->offs, buf->len);
134
135 buf->nstack--;
136 buf->offs = buf->stack[buf->nstack].offs;
137 buf->len += buf->stack[buf->nstack].len;
138
139 buf->data = buf->adata + buf->offs;
140
141 DM_DBG(
142 " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n",
143 buf->nstack, buf->offs, buf->len);
144
145 }
146 else
147 DM_DBG("dmGrowBufPop(%p)\n", buf);
148 }
149
150
151 static BOOL dmGrowBufRealloc(DMGrowBuf *buf, const size_t nsize, const BOOL clear) 100 static BOOL dmGrowBufRealloc(DMGrowBuf *buf, const size_t nsize, const BOOL clear)
152 { 101 {
153 DM_DBG("dmGrowBufRealloc(%p): size=%" DM_PRIu_SIZE_T "\n" 102 DM_DBG("dmGrowBufRealloc(%p):\n"
154 " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n", 103 " size=%" DM_PRIu_SIZE_T ", nsize=" DM_PRIu_SIZE_T
155 buf, buf->size, buf->nstack, buf->offs, buf->len); 104 ", nstack=%d, offs=%" DM_PRIu_SIZE_T "\n",
156 105 buf, buf->size, nsize, buf->nstack, buf->offs);
157 if ((buf->adata = dmRealloc(buf->adata, nsize)) == NULL) 106
158 return FALSE; 107 // Can't be smaller than current size!
159 108 if (nsize < buf->size)
109 return FALSE;
110
111 if ((buf->data = dmRealloc(buf->data, nsize)) == NULL)
112 return FALSE;
113
114 // For buffers growing backwards, we must move the
115 // current data to the end of the buffer ..
116 size_t clrsize = nsize - buf->size;
117 if (buf->backwards)
118 {
119 memmove(buf->data + clrsize, buf->data, clrsize);
120 buf->offs += clrsize;
121 }
122
123 // Check if we need to clear the newly allocated area?
160 if (clear) 124 if (clear)
161 memset(buf->adata + buf->size, 0, nsize - buf->size); 125 {
162 126 if (buf->backwards)
163 buf->data = buf->adata + buf->offs; 127 memset(buf->data, 0, clrsize);
128 else
129 memset(buf->data + buf->size, 0, clrsize);
130 }
131
164 buf->size = nsize; 132 buf->size = nsize;
165 133
166 return TRUE; 134 return TRUE;
167 } 135 }
168 136
172 // if there is not enough space for at least that amount compared to 140 // if there is not enough space for at least that amount compared to
173 // current buffer "len". 141 // current buffer "len".
174 // 142 //
175 BOOL dmGrowBufGrow(DMGrowBuf *buf, const size_t amount) 143 BOOL dmGrowBufGrow(DMGrowBuf *buf, const size_t amount)
176 { 144 {
177 if (buf->adata == NULL || buf->offs + buf->len + amount >= buf->size) 145 size_t grow = (amount > buf->mingrow) ? amount : buf->mingrow;
178 { 146
179 size_t grow = (amount > buf->mingrow) ? amount : buf->mingrow; 147 if (buf->data == NULL ||
180 if (!dmGrowBufRealloc(buf, buf->offs + buf->len + grow, TRUE)) 148 (buf->backwards && amount >= buf->offs) ||
149 (!buf->backwards && buf->offs + amount >= buf->size))
150 {
151 if (!dmGrowBufRealloc(buf, buf->size + grow, TRUE))
181 return FALSE; 152 return FALSE;
182 } 153 }
183 154
155 buf->len += amount;
184 return TRUE; 156 return TRUE;
185 } 157 }
186 158
187 159
188 // 160 //
189 // Grow the buffer if "nsize" is larger than the current buffer size. 161 // Grow the buffer if "nsize" is larger than the current buffer size.
190 // Buffer is enlarged to nsize + mingrow. 162 // Buffer is enlarged to nsize + mingrow.
191 // 163 //
192 BOOL dmGrowBufCheckGrow(DMGrowBuf *buf, const size_t nsize) 164 BOOL dmGrowBufCheckGrow(DMGrowBuf *buf, const size_t nsize)
193 { 165 {
194 if (buf->adata == NULL || buf->offs + nsize > buf->size) 166 if (buf->data == NULL || nsize > buf->size)
195 { 167 {
196 if (!dmGrowBufRealloc(buf, buf->offs + nsize + buf->mingrow, TRUE)) 168 if (!dmGrowBufRealloc(buf, nsize + buf->mingrow, TRUE))
197 return FALSE; 169 return FALSE;
198 } 170 }
199 171
172 buf->len = nsize;
173 return TRUE;
174 }
175
176
177 static void dmGrowBufUpdate(DMGrowBuf *buf)
178 {
179 if (buf->offs < buf->min_offs)
180 buf->min_offs = buf->offs;
181
182 if (buf->offs > buf->max_offs)
183 buf->max_offs = buf->offs;
184 }
185
186
187 BOOL dmGrowBufPut(DMGrowBuf *buf, const Uint8 *data, const size_t len)
188 {
189 if (data == NULL)
190 return FALSE;
191
192 if (!dmGrowBufGrow(buf, len))
193 return FALSE;
194
195 if (buf->backwards)
196 {
197 if (buf->literal)
198 {
199 buf->offs -= len;
200 memcpy(buf->data + buf->offs, data, len);
201 }
202 else
203 {
204 for (size_t n = 0; n < len; n++)
205 buf->data[buf->offs--] = data[n];
206 }
207 }
208 else
209 {
210 memcpy(buf->data + buf->offs, data, len);
211 buf->offs += len;
212 }
213
214 dmGrowBufUpdate(buf);
215
200 return TRUE; 216 return TRUE;
201 } 217 }
202 218
203 219
204 BOOL dmGrowBufPutU8(DMGrowBuf *buf, const Uint8 value) 220 BOOL dmGrowBufPutU8(DMGrowBuf *buf, const Uint8 value)
205 { 221 {
206 if (!dmGrowBufGrow(buf, sizeof(Uint8))) 222 if (!dmGrowBufGrow(buf, sizeof(Uint8)))
207 return FALSE; 223 return FALSE;
208 224
209 buf->data[buf->len++] = value; 225 buf->data[buf->offs] = value;
210 226 if (buf->backwards)
211 return TRUE; 227 buf->offs--;
212 } 228 else
213 229 buf->offs++;
214 230
215 BOOL dmGrowBufPut(DMGrowBuf *buf, const void *str, const size_t len) 231 dmGrowBufUpdate(buf);
216 {
217 if (str == NULL)
218 return FALSE;
219
220 if (!dmGrowBufGrow(buf, len))
221 return FALSE;
222
223 memcpy(buf->data + buf->len, str, len);
224 buf->len += len;
225 232
226 return TRUE; 233 return TRUE;
227 } 234 }
228 235
229 236
230 BOOL dmGrowBufPutU16BE(DMGrowBuf *buf, const Uint16 val) 237 BOOL dmGrowBufPutU16BE(DMGrowBuf *buf, const Uint16 val)
231 { 238 {
232 if (!dmGrowBufGrow(buf, sizeof(Uint16))) 239 if (buf->literal && buf->backwards)
233 return FALSE; 240 {
234 241 return
235 buf->data[buf->len++] = (val >> 8) & 0xff; 242 !dmGrowBufPutU8(buf, val & 0xff) ||
236 buf->data[buf->len++] = val & 0xff; 243 !dmGrowBufPutU8(buf, (val >> 8) & 0xff);
237 244 }
238 return TRUE; 245 else
246 {
247 return
248 !dmGrowBufPutU8(buf, (val >> 8) & 0xff) ||
249 !dmGrowBufPutU8(buf, val & 0xff);
250 }
239 } 251 }
240 252
241 253
242 BOOL dmGrowBufPutU16LE(DMGrowBuf *buf, const Uint16 val) 254 BOOL dmGrowBufPutU16LE(DMGrowBuf *buf, const Uint16 val)
243 { 255 {
244 if (!dmGrowBufGrow(buf, sizeof(Uint16))) 256 if (buf->literal && buf->backwards)
245 return FALSE; 257 {
246 258 return
247 buf->data[buf->len++] = val & 0xff; 259 !dmGrowBufPutU8(buf, (val >> 8) & 0xff) ||
248 buf->data[buf->len++] = (val >> 8) & 0xff; 260 !dmGrowBufPutU8(buf, val & 0xff);
249 261 }
250 return TRUE; 262 else
263 {
264 return
265 !dmGrowBufPutU8(buf, val & 0xff) ||
266 !dmGrowBufPutU8(buf, (val >> 8) & 0xff);
267 }
251 } 268 }
252 269
253 270
254 BOOL dmGrowBufPutU32BE(DMGrowBuf *buf, const Uint32 val) 271 BOOL dmGrowBufPutU32BE(DMGrowBuf *buf, const Uint32 val)
255 { 272 {
256 if (!dmGrowBufGrow(buf, sizeof(Uint32))) 273 if (buf->literal && buf->backwards)
257 return FALSE; 274 {
258 275 return
259 buf->data[buf->len++] = (val >> 24) & 0xff; 276 !dmGrowBufPutU8(buf, (val >> 24) & 0xff) ||
260 buf->data[buf->len++] = (val >> 16) & 0xff; 277 !dmGrowBufPutU8(buf, (val >> 16) & 0xff) ||
261 buf->data[buf->len++] = (val >> 8) & 0xff; 278 !dmGrowBufPutU8(buf, (val >> 8) & 0xff) ||
262 buf->data[buf->len++] = val & 0xff; 279 !dmGrowBufPutU8(buf, val & 0xff);
263 280 }
264 return TRUE; 281 else
282 {
283 return
284 !dmGrowBufPutU8(buf, val & 0xff) ||
285 !dmGrowBufPutU8(buf, (val >> 8) & 0xff) ||
286 !dmGrowBufPutU8(buf, (val >> 16) & 0xff) ||
287 !dmGrowBufPutU8(buf, (val >> 24) & 0xff);
288 }
265 } 289 }
266 290
267 291
268 BOOL dmGrowBufPutU32LE(DMGrowBuf *buf, const Uint32 val) 292 BOOL dmGrowBufPutU32LE(DMGrowBuf *buf, const Uint32 val)
269 { 293 {
270 if (!dmGrowBufGrow(buf, sizeof(Uint32))) 294 if (buf->literal && buf->backwards)
271 return FALSE; 295 {
272 296 return
273 buf->data[buf->len++] = val & 0xff; 297 !dmGrowBufPutU8(buf, val & 0xff) ||
274 buf->data[buf->len++] = (val >> 8) & 0xff; 298 !dmGrowBufPutU8(buf, (val >> 8) & 0xff) ||
275 buf->data[buf->len++] = (val >> 16) & 0xff; 299 !dmGrowBufPutU8(buf, (val >> 16) & 0xff) ||
276 buf->data[buf->len++] = (val >> 24) & 0xff; 300 !dmGrowBufPutU8(buf, (val >> 24) & 0xff);
277 301 }
278 return TRUE; 302 else
279 } 303 {
304 return
305 !dmGrowBufPutU8(buf, (val >> 24) & 0xff) ||
306 !dmGrowBufPutU8(buf, (val >> 16) & 0xff) ||
307 !dmGrowBufPutU8(buf, (val >> 8) & 0xff) ||
308 !dmGrowBufPutU8(buf, val & 0xff);
309 }
310 }