Mercurial > code
annotate buffer.c @ 104:c66fb578a7c4
Cosmetic
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 17 Jan 2012 13:51:33 +0100 |
parents | 37eef6776cc6 |
children |
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 * |
98 | 4 * Copyright (c) 2011, 2012, David Demelier <markand@malikania.fr> |
0
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 /* |
101
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
29 * Initialize a new buffer. |
0
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 |
101
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
32 int |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
33 buffer_init(struct buffer *buf) |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 { |
101
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
35 /* Set defaults if needed */ |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
36 buf->bsize = (buf->length == 0) ? BUFFER_DEFAULT_BSIZE : buf->length; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
37 buf->size = buf->bsize + 1; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
38 buf->malloc = (buf->malloc == NULL) ? &malloc : buf->malloc; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
39 buf->realloc = (buf->realloc == NULL) ? &realloc : buf->realloc; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
40 |
101
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
41 if ((buf->text = buf->malloc(buf->size)) == NULL) { |
28
904a373aa120
Buffer security fix. Also switched to == NULL statement instead of ! as
David Demelier <markand@malikania.fr>
parents:
21
diff
changeset
|
42 free(buf); |
101
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
43 return -1; |
28
904a373aa120
Buffer security fix. Also switched to == NULL statement instead of ! as
David Demelier <markand@malikania.fr>
parents:
21
diff
changeset
|
44 } |
904a373aa120
Buffer security fix. Also switched to == NULL statement instead of ! as
David Demelier <markand@malikania.fr>
parents:
21
diff
changeset
|
45 |
101
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
46 memset(buf->text, 0, buf->size); |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
47 |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
48 return 0; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
49 } |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
50 |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
51 /* |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
52 * Valid options that can be set for a buffer : |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
53 * l -> optional buffer block size of type int |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
54 * m -> malloc function that must matches void * (*malloc)(size_t) |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
55 * r -> realloc function that must matches void * (*realloc)(void *, size_t) |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
56 * t -> type of array of type enum array_type |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
57 */ |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
58 |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
59 void |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
60 buffer_set(struct buffer *buf, const char *fmt, ...) |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
61 { |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
62 va_list ap; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
63 const char *p; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
64 |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
65 va_start(ap, fmt); |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
66 for (p = fmt; *p != '\0'; ++p) |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
67 switch (*p) { |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
68 case 'l': |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
69 buf->bsize = va_arg(ap, int); |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
70 break; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
71 case 'm': |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
72 buf->malloc = va_arg(ap, void *(*)(size_t)); |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
73 break; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
74 case 'r': |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
75 buf->realloc = va_arg(ap, void *(*)(void *, size_t)); |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
76 break; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
77 case 't': |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
78 buf->type = va_arg(ap, int); |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
79 break; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
80 default: |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
81 break; |
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
82 } |
0
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 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 * Concatenate the string into the buffer. |
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 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 buffer_strcat(struct buffer *buf, const char *str) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 size_t length; |
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 length = strlen(str); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 if (buffer_grow(buf, length) < 0) |
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 |
47 | 98 if (buf->type == BUFFER_AUTO) |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 length = buf->size - buf->length - 1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
101 strncpy(buf->text + buf->length, str, length); |
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
102 buf->length = strlen(buf->text); |
0
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 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 } |
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 /* |
47 | 108 * Append the character `c' to the end of buffer. |
1 | 109 */ |
110 | |
111 int | |
112 buffer_putc(struct buffer *buf, char c) | |
113 { | |
114 if (buffer_grow(buf, 1) < 0) | |
115 return -1; | |
116 | |
47 | 117 if (buf->type != BUFFER_AUTO && buf->size - buf->length - 1 <= 2) |
21
ae4128d16c92
Improve security and FIXED size buffer
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
118 return -1; |
ae4128d16c92
Improve security and FIXED size buffer
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
119 |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
120 buf->text[buf->length++] = c; |
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
121 buf->text[buf->length] = '\0'; |
1 | 122 |
123 return 0; | |
124 } | |
125 | |
126 /* | |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
127 * Concatenate the byte pointer into the buffer. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
128 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
129 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
130 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
131 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
|
132 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
133 if (buffer_grow(buf, size) < 0) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
134 return -1; |
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 /* Do not truncate void pointer */ |
47 | 137 if (buf->type == BUFFER_AUTO && size > (buf->size - buf->length - 1)) |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
138 return -1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
139 |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
140 memcpy(buf->text + buf->length, data, size); |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
141 buf->length += size; |
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 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
144 } |
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 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
147 * 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
|
148 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
149 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
150 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
151 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
|
152 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
153 va_list ap_save; |
1 | 154 int nb, result = 1; |
0
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 * 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
|
158 * should be printed... |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
159 */ |
47 | 160 if (buf->type == BUFFER_AUTO) { |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
161 do { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
162 va_copy(ap_save, ap); |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
163 nb = vsnprintf(buf->text + buf->length, |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
164 buf->size - buf->length - 1, fmt, ap_save); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
165 |
41
5252fa9b5cb1
Little update for buffer
David Demelier <markand@malikania.fr>
parents:
28
diff
changeset
|
166 if (nb == -1 || (size_t) nb >= buf->size - buf->length - 1) { |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
167 if (buffer_grow(buf, buf->size + buf->bsize)) |
1 | 168 result = -1; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
169 } else |
1 | 170 result = 0; |
171 } while (result == 1); | |
172 | |
173 va_end(ap_save); | |
174 } else { | |
175 result = 0; | |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
176 vsnprintf(buf->text + buf->length, buf->size - buf->length - 1, |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
177 fmt, ap); |
1 | 178 } |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
179 |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
180 buf->length = strlen(buf->text); |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 |
1 | 182 return result; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
183 } |
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 * 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
|
187 */ |
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 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
190 buffer_printf(struct buffer *buf, const char *fmt, ...) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
191 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
192 va_list ap; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
193 int status; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
194 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
195 va_start(ap, fmt); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
196 status = buffer_vprintf(buf, fmt, ap); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
197 va_end(ap); |
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 return status; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
200 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
201 |
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 * 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
|
204 */ |
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 int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
207 buffer_shrink(struct buffer *buf) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
208 { |
101
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
209 if ((buf->text = buf->realloc(buf->text, buf->length + 1)) == NULL) { |
52
14c0b77f679b
Add buffer_shrink in buffer_end() and security if realloc fails
David Demelier <markand@malikania.fr>
parents:
47
diff
changeset
|
210 buf->size = 0; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
211 return -1; |
52
14c0b77f679b
Add buffer_shrink in buffer_end() and security if realloc fails
David Demelier <markand@malikania.fr>
parents:
47
diff
changeset
|
212 } |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
213 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
214 buf->size = buf->length + 1; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
215 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
216 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
217 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
218 |
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 * 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
|
221 */ |
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 char * |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
224 buffer_end(struct buffer *buf) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
225 { |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
226 char *text; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
227 |
52
14c0b77f679b
Add buffer_shrink in buffer_end() and security if realloc fails
David Demelier <markand@malikania.fr>
parents:
47
diff
changeset
|
228 buffer_shrink(buf); |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
229 text = buf->text; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
230 free(buf); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
231 |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
232 return text; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
233 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
234 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
235 /* |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
236 * Reset the struct buffer. |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
237 */ |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
238 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
239 void |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
240 buffer_clear(struct buffer *buf) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
241 { |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
242 memset(buf->text, 0, buf->size); |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
243 buf->length = 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
244 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
245 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
246 void |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
247 buffer_free(struct buffer *buf) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
248 { |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
249 buffer_clear(buf); |
45
86dbd57a39de
Do not free data in buffer_clear, we may want reusing
David Demelier <markand@malikania.fr>
parents:
41
diff
changeset
|
250 |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
251 if (buf->text) |
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
252 free(buf->text); |
45
86dbd57a39de
Do not free data in buffer_clear, we may want reusing
David Demelier <markand@malikania.fr>
parents:
41
diff
changeset
|
253 |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
254 free(buf); |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
255 } |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
256 |
1 | 257 /* |
258 * Functions that tries to extend the buffer to the `needed' size if the buffer | |
259 * allows it. If the buffer is fixed size and there is not enough space the | |
260 * functions returns -1 otherwise 0 is returned. | |
261 */ | |
262 | |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
263 static int |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
264 buffer_grow(struct buffer *buf, size_t needed) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
265 { |
15
520939b40002
Do not increate buf->size on realloc failure
David Demelier <markand@malikania.fr>
parents:
5
diff
changeset
|
266 size_t newlen; |
520939b40002
Do not increate buf->size on realloc failure
David Demelier <markand@malikania.fr>
parents:
5
diff
changeset
|
267 |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
268 if ((buf->size - buf->length) > needed) |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
269 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
270 |
47 | 271 if (buf->type == BUFFER_AUTO) { |
15
520939b40002
Do not increate buf->size on realloc failure
David Demelier <markand@malikania.fr>
parents:
5
diff
changeset
|
272 newlen = buf->size; |
21
ae4128d16c92
Improve security and FIXED size buffer
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
273 while (newlen - buf->length - 1 <= needed) |
15
520939b40002
Do not increate buf->size on realloc failure
David Demelier <markand@malikania.fr>
parents:
5
diff
changeset
|
274 newlen += buf->bsize; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
275 |
101
37eef6776cc6
Update buffer like array and parray
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
276 if ((buf->text = buf->realloc(buf->text, newlen)) == NULL) { |
52
14c0b77f679b
Add buffer_shrink in buffer_end() and security if realloc fails
David Demelier <markand@malikania.fr>
parents:
47
diff
changeset
|
277 buf->size = 0; |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
278 return -1; |
52
14c0b77f679b
Add buffer_shrink in buffer_end() and security if realloc fails
David Demelier <markand@malikania.fr>
parents:
47
diff
changeset
|
279 } |
15
520939b40002
Do not increate buf->size on realloc failure
David Demelier <markand@malikania.fr>
parents:
5
diff
changeset
|
280 |
520939b40002
Do not increate buf->size on realloc failure
David Demelier <markand@malikania.fr>
parents:
5
diff
changeset
|
281 buf->size = newlen; |
53
bbe0713e8e2a
Rename member to text, more useful
David Demelier <markand@malikania.fr>
parents:
52
diff
changeset
|
282 memset(buf->text + buf->length, 0, buf->size - buf->length); |
21
ae4128d16c92
Improve security and FIXED size buffer
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
283 } |
0
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
284 |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
285 return 0; |
a20beb164de8
Added buffer.c and buffer.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
286 } |