Libparserutils
buffer.c
Go to the documentation of this file.
1/*
2 * This file is part of LibParserUtils.
3 * Licensed under the MIT License,
4 * http://www.opensource.org/licenses/mit-license.php
5 * Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org>
6 */
7
8#include <string.h>
9#include <stdarg.h>
10
12
13#define DEFAULT_SIZE (4096)
14
24{
26
27 if (buffer == NULL)
29
30 b = malloc(sizeof(parserutils_buffer));
31 if (b == NULL)
32 return PARSERUTILS_NOMEM;
33
34 b->alloc = malloc(DEFAULT_SIZE);
35 if (b->alloc == NULL) {
36 free(b);
37 return PARSERUTILS_NOMEM;
38 }
39
40 b->data = b->alloc;
41 b->length = 0;
43
44 *buffer = b;
45
46 return PARSERUTILS_OK;
47}
48
56{
57 if (buffer == NULL)
59
60 free(buffer->alloc);
61 free(buffer);
62
63 return PARSERUTILS_OK;
64}
65
72static inline size_t get_offset(parserutils_buffer *buffer)
73{
74 return buffer->data - buffer->alloc;
75}
76
82static inline void try_rebase(parserutils_buffer *buffer)
83{
84 if (get_offset(buffer) >= buffer->length) {
85 memcpy(buffer->alloc, buffer->data, buffer->length);
86 buffer->data = buffer->alloc;
87 }
88}
89
98 parserutils_buffer *buffer,
99 size_t len)
100{
101 try_rebase(buffer);
102
103 while (len >= buffer->allocated - buffer->length - get_offset(buffer)) {
105 if (error != PARSERUTILS_OK)
106 return error;
107 }
108
109 return PARSERUTILS_OK;
110}
111
121 const uint8_t *data, size_t len)
122{
123 parserutils_error error = ensure_space(buffer, len);
124 if (error != PARSERUTILS_OK)
125 return error;
126
127 memcpy(buffer->data + buffer->length, data, len);
128
129 buffer->length += len;
130
131 return PARSERUTILS_OK;
132}
133
145 size_t count, ...)
146{
147 va_list ap;
149 const uint8_t *data;
150 size_t len;
151
152 va_start(ap, count);
153 while (count > 0) {
154 data = va_arg(ap, const uint8_t *);
155 len = va_arg(ap, size_t);
156 error = parserutils_buffer_append(buffer, data, len);
157 if (error != PARSERUTILS_OK)
158 break;
159 count--;
160 }
161 va_end(ap);
162
163 return error;
164}
165
176 size_t offset, const uint8_t *data, size_t len)
177{
178 parserutils_error error;
179
180 if (offset > buffer->length)
181 return PARSERUTILS_BADPARM;
182
183 if (offset == buffer->length)
184 return parserutils_buffer_append(buffer, data, len);
185
186 error = ensure_space(buffer, len);
187 if (error != PARSERUTILS_OK)
188 return error;
189
190 memmove(buffer->data + offset + len,
191 buffer->data + offset, buffer->length - offset);
192
193 memcpy(buffer->data + offset, data, len);
194
195 buffer->length += len;
196
197 return PARSERUTILS_OK;
198}
199
209 size_t offset, size_t len)
210{
211 if (offset >= buffer->length || offset + len > buffer->length)
212 return PARSERUTILS_BADPARM;
213
214 if (offset == 0) {
215 buffer->data += len;
216 buffer->length -= len;
217 try_rebase(buffer);
218 return PARSERUTILS_OK;
219 }
220
221 memmove(buffer->data + offset, buffer->data + offset + len,
222 buffer->length - (len + offset));
223
224 buffer->length -= len;
225
226 return PARSERUTILS_OK;
227}
228
236{
237 size_t offset = get_offset(buffer);
238 uint8_t *temp = realloc(buffer->alloc, buffer->allocated * 2);
239 if (temp == NULL)
240 return PARSERUTILS_NOMEM;
241
242 buffer->alloc = temp;
243 buffer->data = buffer->alloc + offset;
244 buffer->allocated *= 2;
245
246 return PARSERUTILS_OK;
247}
248
250{
251#ifndef NDEBUG
252 uint8_t *temp;
253#endif
254
255 if (buffer == NULL)
256 return PARSERUTILS_BADPARM;
257
258#ifndef NDEBUG
259 temp = malloc(buffer->allocated);
260 if (temp == NULL)
261 return PARSERUTILS_NOMEM;
262
263 memcpy(temp, buffer->data, buffer->length);
264
265 memset(buffer->data, 0xff, buffer->length);
266
267 /* Leak the buffer's current data, so we don't reuse it */
268 /* buffer->alloc(buffer->data, 0, buffer->pw); */
269
270 buffer->alloc = buffer->data = temp;
271#endif
272
273
274 return PARSERUTILS_OK;
275}
276
parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer, size_t offset, const uint8_t *data, size_t len)
Insert data into a memory buffer.
Definition buffer.c:175
parserutils_error parserutils_buffer_randomise(parserutils_buffer *buffer)
Definition buffer.c:249
parserutils_error parserutils_buffer_create(parserutils_buffer **buffer)
Create a memory buffer.
Definition buffer.c:23
parserutils_error parserutils_buffer_destroy(parserutils_buffer *buffer)
Destroy a memory buffer.
Definition buffer.c:55
static size_t get_offset(parserutils_buffer *buffer)
Get current data offset within buffer's allocation.
Definition buffer.c:72
static parserutils_error ensure_space(parserutils_buffer *buffer, size_t len)
Ensure that the buffer has enough space at the end to add len bytes.
Definition buffer.c:97
#define DEFAULT_SIZE
Definition buffer.c:13
parserutils_error parserutils_buffer_append(parserutils_buffer *buffer, const uint8_t *data, size_t len)
Append data to a memory buffer.
Definition buffer.c:120
parserutils_error parserutils_buffer_grow(parserutils_buffer *buffer)
Extend the amount of space allocated for a memory buffer.
Definition buffer.c:235
static void try_rebase(parserutils_buffer *buffer)
Try moving the data to the start of the allocation.
Definition buffer.c:82
parserutils_error parserutils_buffer_appendv(parserutils_buffer *buffer, size_t count,...)
Append multiple data blocks to a memory buffer.
Definition buffer.c:144
parserutils_error parserutils_buffer_discard(parserutils_buffer *buffer, size_t offset, size_t len)
Discard a section of a memory buffer.
Definition buffer.c:208
size_t len
Definition codec_8859.c:23
parserutils_error
Definition errors.h:18
@ PARSERUTILS_OK
Definition errors.h:19
@ PARSERUTILS_NOMEM
Definition errors.h:21
@ PARSERUTILS_BADPARM
Definition errors.h:22
uint8_t * data
Definition buffer.h:22
uint8_t * alloc
Definition buffer.h:21
size_t allocated
Definition buffer.h:24