summaryrefslogtreecommitdiff
path: root/src/ot_iovec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ot_iovec.c')
-rw-r--r--src/ot_iovec.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/ot_iovec.c b/src/ot_iovec.c
new file mode 100644
index 0000000..328f160
--- /dev/null
+++ b/src/ot_iovec.c
@@ -0,0 +1,87 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4/* System */
5#include <stdlib.h>
6#include <sys/uio.h>
7
8/* Opentracker */
9#include "ot_iovec.h"
10
11void *iovec_new_chunk(size_t *iovec_entries, struct iovec **iovector, size_t new_alloc) {
12 void *new_data;
13 size_t new_entries = 1 + *iovec_entries;
14 struct iovec *new_vec = realloc(*iovector, new_entries * sizeof(struct iovec));
15
16 if (!new_vec)
17 return NULL;
18
19 *iovector = new_vec;
20
21 /* Only allocate after we have a place to store the pointer */
22 new_data = malloc(new_alloc);
23 if (!new_data)
24 return NULL;
25
26 new_vec[new_entries - 1].iov_base = new_data;
27 new_vec[new_entries - 1].iov_len = new_alloc;
28
29 ++*iovec_entries;
30 return new_data;
31}
32
33void *iovec_append(size_t *iovec_entries, struct iovec **iovector, struct iovec *append_iovector) {
34 size_t new_entries = *iovec_entries + 1;
35 struct iovec *new_vec = realloc(*iovector, new_entries * sizeof(struct iovec));
36 if (!new_vec)
37 return NULL;
38
39 /* Take over data from appended iovec */
40 new_vec[*iovec_entries].iov_base = append_iovector->iov_base;
41 new_vec[*iovec_entries].iov_len = append_iovector->iov_len;
42
43 append_iovector->iov_base = NULL;
44 append_iovector->iov_len = 0;
45
46 *iovector = new_vec;
47 *iovec_entries = new_entries;
48
49 return new_vec;
50}
51
52void iovec_free(size_t *iovec_entries, struct iovec **iovector) {
53 size_t i;
54 for (i = 0; i < *iovec_entries; ++i)
55 free(((*iovector)[i]).iov_base);
56 free(*iovector);
57 *iovector = NULL;
58 *iovec_entries = 0;
59}
60
61void iovec_trim_last(size_t *iovec_entries, struct iovec **iovector, void *last_ptr) {
62 if (*iovec_entries) {
63 char *base = (char *)((*iovector)[*iovec_entries - 1]).iov_base;
64 size_t new_alloc = ((char *)last_ptr) - base;
65
66 ((*iovector)[*iovec_entries - 1]).iov_base = realloc(base, new_alloc);
67 ((*iovector)[*iovec_entries - 1]).iov_len = new_alloc;
68 }
69}
70
71void *iovec_next_chunk(size_t *iovec_entries, struct iovec **iovector, void *last_ptr, size_t new_alloc) {
72 void *new_data;
73
74 iovec_trim_last(iovec_entries, iovector, last_ptr);
75
76 if (!(new_data = iovec_new_chunk(iovec_entries, iovector, new_alloc)))
77 iovec_free(iovec_entries, iovector);
78
79 return new_data;
80}
81
82size_t iovec_length(const size_t *iovec_entries, const struct iovec **iovector) {
83 size_t i, length = 0;
84 for (i = 0; i < *iovec_entries; ++i)
85 length += ((*iovector)[i]).iov_len;
86 return length;
87}