annotate buffer.c @ 254:de0709ff0895

buffer: add a borrowed-const-data buffer type At times it is useful to wrap a const blob of memory in a buffer structure to allow it to be used by consumers expecting a (read-only) struct buffer. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Sun, 09 Jul 2017 10:24:08 +0300
parents 5f9eebf77662
children f82b45b662c9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
250
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
1 /*
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
2 * Copyright (c) 2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
3 *
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
5 * of this software and associated documentation files (the "Software"), to deal
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
6 * in the Software without restriction, including without limitation the rights
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
8 * copies of the Software, and to permit persons to whom the Software is
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
9 * furnished to do so, subject to the following conditions:
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
10 *
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
11 * The above copyright notice and this permission notice shall be included in
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
12 * all copies or substantial portions of the Software.
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
13 *
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
20 * SOFTWARE.
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
21 */
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
22
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
23 #include <stdbool.h>
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
24
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
25 #include <jeffpc/buffer.h>
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
26
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
27 struct buffer *buffer_alloc(size_t expected_size)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
28 {
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
29 struct buffer *buffer;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
30
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
31 buffer = malloc(sizeof(struct buffer));
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
32 if (!buffer)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
33 return ERR_PTR(-ENOMEM);
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
34
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
35 buffer->data = malloc(expected_size ? expected_size : 1);
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
36 if (!buffer->data) {
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
37 free(buffer);
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
38 return ERR_PTR(-ENOMEM);
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
39 }
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
40
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
41 buffer->used = 0;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
42 buffer->allocsize = expected_size;
251
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
43 buffer->sink = false;
254
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
44 buffer->heap = true;
250
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
45
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
46 return buffer;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
47 }
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
48
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
49 void buffer_free(struct buffer *buffer)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
50 {
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
51 if (!buffer)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
52 return;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
53
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
54 free(buffer->data);
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
55 free(buffer);
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
56 }
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
57
251
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
58 void buffer_init_sink(struct buffer *buffer)
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
59 {
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
60 buffer->data = NULL;
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
61 buffer->used = 0;
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
62 buffer->allocsize = SIZE_MAX;
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
63 buffer->sink = true;
254
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
64 buffer->heap = false;
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
65
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
66 }
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
67
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
68 void buffer_init_const(struct buffer *buffer, const void *data, size_t size)
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
69 {
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
70 buffer->data = (void *) data;
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
71 buffer->used = size;
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
72 buffer->allocsize = size;
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
73 buffer->sink = false;
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
74 buffer->heap = false;
251
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
75 }
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
76
250
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
77 static int resize(struct buffer *buffer, size_t newsize)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
78 {
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
79 void *tmp;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
80
251
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
81 ASSERT(!buffer->sink);
254
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
82 ASSERT(buffer->heap);
251
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
83
250
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
84 if (newsize <= buffer->allocsize)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
85 return 0;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
86
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
87 tmp = realloc(buffer->data, newsize);
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
88 if (!tmp)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
89 return -ENOMEM;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
90
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
91 buffer->data = tmp;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
92
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
93 return 0;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
94 }
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
95
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
96 int buffer_append(struct buffer *buffer, const void *data, size_t size)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
97 {
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
98 int ret;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
99
254
de0709ff0895 buffer: add a borrowed-const-data buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 251
diff changeset
100 if (!buffer || (!buffer->sink && !buffer->heap))
250
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
101 return -EINVAL;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
102
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
103 if (!data && !size)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
104 return 0; /* append(..., NULL, 0) is a no-op */
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
105
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
106 if (!data || !size)
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
107 return -EINVAL;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
108
251
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
109 if (!buffer->sink) {
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
110 ret = resize(buffer, buffer->used + size);
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
111 if (ret)
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
112 return ret;
250
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
113
251
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
114 memcpy(buffer->data + buffer->used, data, size);
5f9eebf77662 buffer: add a sinkhole buffer type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 250
diff changeset
115 }
250
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
116
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
117 buffer->used += size;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
118
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
119 return 0;
0e4e45813eb9 buffer: introduce a simple growing memory buffer API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
120 }