Mercurial > code
annotate buffer.c @ 0:a20beb164de8
Added buffer.c and buffer.h:
Various function to manipulate safely string buffers. It is similar to
sbuf(9) on FreeBSD but more portable and simpler.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 05 Sep 2011 23:01:29 +0200 |
parents | |
children | 22d7bb03e569 |
rev | line source |
---|---|
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * buffer.c -- safe unlimited size string |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2011, David Demelier <markand@malikania.fr> |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
19 #include <stdio.h> |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
20 #include <stdlib.h> |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 #include <stdarg.h> |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 #include <string.h> |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
23 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 #include "buffer.h" |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 static int buffer_grow(struct buffer *, size_t); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
29 * Initialize a new buffer with the optional `str' as begin of buffer. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
30 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
31 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
32 struct buffer * |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
33 buffer_new(const char *str, size_t bsize, int flags) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
35 struct buffer *buf; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
36 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 if (!(buf = malloc(sizeof (struct buffer)))) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
38 return NULL; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
39 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
40 memset(buf, 0, sizeof (struct buffer)); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
41 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
42 if (bsize == 0) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
43 bsize = BUFFER_DEFAULT_BSIZE; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
44 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
45 if (!(buf->data = calloc(bsize + 1, 1))) { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
46 free(buf); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
47 return NULL; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
48 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
49 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
50 buf->size = bsize + 1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
51 buf->bsize = bsize; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
52 buf->flags = flags; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
53 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
54 if (str && buffer_strcat(buf, str) < 0) { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 free(buf); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 return NULL; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
57 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
58 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
59 return buf; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
60 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
61 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
62 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
63 * Concatenate the string into the buffer. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
64 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
65 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
66 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
67 buffer_strcat(struct buffer *buf, const char *str) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
68 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 size_t length; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 length = strlen(str); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 if (buffer_grow(buf, length) < 0) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
73 return -1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
74 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 if (buf->flags & BUFFER_FIXED) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
76 length = buf->size - buf->length - 1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 strncat(buf->data, str, length); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 buf->length = strlen(buf->data); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
80 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
81 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
82 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
83 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
85 * Concatenate the byte pointer into the buffer. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
88 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 buffer_bcat(struct buffer *buf, const void *data, size_t size) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 if (buffer_grow(buf, size) < 0) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 return -1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 /* Do not truncate void pointer */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 if (buf->flags & BUFFER_FIXED && size > (buf->size - buf->length - 1)) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
96 return -1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 memcpy(buf->data + buf->length, data, size); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 buf->length += size; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
101 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
102 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
103 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
104 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 * Print into the buffer using va_list from stdarg.h |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 buffer_vprintf(struct buffer *buf, const char *fmt, va_list ap) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
110 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 va_list ap_save; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 int nb, stop = 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
113 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
114 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 * vsnprintf on windows returns -1 instead of the number of bytes that |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
116 * should be printed... |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
117 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
118 if (buf->flags & BUFFER_AUTO) { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 do { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 va_copy(ap_save, ap); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 nb = vsnprintf(buf->data + buf->length, |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
122 buf->size - buf->length - 1, fmt, ap_save); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
123 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
124 if (nb == -1 || nb > strlen(buf->data)) { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
125 if (buffer_grow(buf, buf->size + buf->bsize)) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
126 return -1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
127 } else |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
128 stop = 1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
129 } while (stop == 0); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
130 } else |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
131 vsnprintf(buf->data + buf->length, buf->size - buf->length - 1, |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
132 fmt, ap); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
133 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
134 va_end(ap_save); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
135 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
136 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
137 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
138 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
139 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
140 * Use printf(3) functions like to write into the buffer. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
141 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
142 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
143 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
144 buffer_printf(struct buffer *buf, const char *fmt, ...) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
145 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
146 va_list ap; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
147 int status; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
148 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
149 va_start(ap, fmt); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
150 status = buffer_vprintf(buf, fmt, ap); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
151 va_end(ap); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
152 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
153 return status; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
154 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
155 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
156 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
157 * Reduce the data buffer to the exact size. Returns -1 on failure. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
158 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
159 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
160 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
161 buffer_shrink(struct buffer *buf) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
162 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
163 if (!(buf->data = realloc(buf->data, buf->length + 1))) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
164 return -1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
165 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
166 buf->size = buf->length + 1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
167 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
168 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
169 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
170 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
171 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
172 * Returns the buffer data and then free the buffer object. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
173 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
174 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
175 char * |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
176 buffer_end(struct buffer *buf) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
177 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
178 char *data; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
179 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
180 data = buf->data; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 free(buf); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
182 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
183 return data; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
184 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
185 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
186 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
187 * Reset the struct buffer. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
188 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
189 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
190 void |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
191 buffer_clear(struct buffer *buf) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
192 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
193 if (buf->data) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
194 free(buf->data); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
195 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
196 buf->length = 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
197 buf->size = 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
198 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
199 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
200 void |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
201 buffer_free(struct buffer *buf) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
202 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
203 buffer_clear(buf); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
204 free(buf); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
205 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
206 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
207 static int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
208 buffer_grow(struct buffer *buf, size_t needed) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
209 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
210 if ((buf->size - buf->length) > needed) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
211 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
212 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
213 if (buf->flags & BUFFER_AUTO) { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
214 while (buf->size - buf->length < needed) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
215 buf->size += buf->bsize; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
216 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
217 if (!(buf->data = realloc(buf->data, buf->size))) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
218 return -1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
219 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
220 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
221 memset(buf->data + buf->length, 0, buf->size - buf->length); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
222 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
223 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
224 } |