blob: 6f10553b0e612447302274b88e285dc782466a7b [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 include/proto/buffers.h
3 Buffer management definitions, macros and inline functions.
4
Willy Tarreau2b7addc2009-08-31 07:37:22 +02005 Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +01006
Willy Tarreaubaaee002006-06-26 02:48:02 +02007 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation, version 2.1
10 exclusively.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#ifndef _PROTO_BUFFERS_H
23#define _PROTO_BUFFERS_H
24
Willy Tarreau7341d942007-05-13 19:56:02 +020025#include <stdio.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010026#include <stdlib.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020027#include <string.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010028
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020029#include <common/config.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020030#include <common/memory.h>
Willy Tarreau0c303ee2008-07-07 00:09:58 +020031#include <common/ticks.h>
Willy Tarreaufa645582007-06-03 15:59:52 +020032#include <common/time.h>
33
Willy Tarreaubaaee002006-06-26 02:48:02 +020034#include <types/buffers.h>
35
Willy Tarreau7341d942007-05-13 19:56:02 +020036extern struct pool_head *pool2_buffer;
37
38/* perform minimal intializations, report 0 in case of error, 1 if OK. */
39int init_buffer();
40
Willy Tarreau03d60bb2009-01-09 11:13:00 +010041/* Initializes all fields in the buffer. The ->max_len field is initialized last
Willy Tarreau54469402006-07-29 16:59:06 +020042 * so that the compiler can optimize it away if changed immediately after the
Willy Tarreaue393fe22008-08-16 22:18:07 +020043 * call to this function. By default, it is set to the full size of the buffer.
Willy Tarreaua07a34e2009-08-16 23:27:46 +020044 * This implies that buffer_init() must only be called once ->size is set !
Willy Tarreauba0b63d2009-09-20 08:09:44 +020045 * The BF_OUT_EMPTY flags is set.
Willy Tarreau54469402006-07-29 16:59:06 +020046 */
47static inline void buffer_init(struct buffer *buf)
48{
Willy Tarreauf890dc92008-12-13 21:12:26 +010049 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +010050 buf->to_forward = 0;
Willy Tarreaue393fe22008-08-16 22:18:07 +020051 buf->l = buf->total = 0;
Willy Tarreau3eba98a2009-01-25 13:56:13 +010052 buf->pipe = NULL;
Willy Tarreau2df28e82008-08-17 15:20:19 +020053 buf->analysers = 0;
Willy Tarreaufa7e1022008-10-19 07:30:41 +020054 buf->cons = NULL;
Willy Tarreauba0b63d2009-09-20 08:09:44 +020055 buf->flags = BF_OUT_EMPTY;
Willy Tarreau2df28e82008-08-17 15:20:19 +020056 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaua07a34e2009-08-16 23:27:46 +020057 buf->max_len = buf->size;
Willy Tarreau54469402006-07-29 16:59:06 +020058}
59
Willy Tarreau2eb52f02008-09-04 09:14:08 +020060/* Check buffer timeouts, and set the corresponding flags. The
61 * likely/unlikely have been optimized for fastest normal path.
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010062 * The read/write timeouts are not set if there was activity on the buffer.
63 * That way, we don't have to update the timeout on every I/O. Note that the
64 * analyser timeout is always checked.
Willy Tarreau2eb52f02008-09-04 09:14:08 +020065 */
66static inline void buffer_check_timeouts(struct buffer *b)
67{
Willy Tarreau86491c32008-12-14 09:04:47 +010068 if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT|BF_READ_ACTIVITY|BF_READ_NOEXP))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020069 unlikely(tick_is_expired(b->rex, now_ms)))
70 b->flags |= BF_READ_TIMEOUT;
71
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010072 if (likely(!(b->flags & (BF_SHUTW|BF_WRITE_TIMEOUT|BF_WRITE_ACTIVITY))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020073 unlikely(tick_is_expired(b->wex, now_ms)))
74 b->flags |= BF_WRITE_TIMEOUT;
75
76 if (likely(!(b->flags & BF_ANA_TIMEOUT)) &&
77 unlikely(tick_is_expired(b->analyse_exp, now_ms)))
78 b->flags |= BF_ANA_TIMEOUT;
79}
80
Willy Tarreau0abebcc2009-01-08 00:09:41 +010081/* Schedule <bytes> more bytes to be forwarded by the buffer without notifying
82 * the task. Any pending data in the buffer is scheduled to be sent as well,
83 * in the limit of the number of bytes to forward. This must be the only method
84 * to use to schedule bytes to be sent. Directly touching ->to_forward will
85 * cause lockups when send_max goes down to zero if nobody is ready to push the
86 * remaining data.
87 */
Willy Tarreau31971e52009-09-20 12:07:52 +020088static inline void buffer_forward(struct buffer *buf, unsigned long bytes)
Willy Tarreau0abebcc2009-01-08 00:09:41 +010089{
Willy Tarreau31971e52009-09-20 12:07:52 +020090 unsigned long data_left;
Willy Tarreau0abebcc2009-01-08 00:09:41 +010091
Willy Tarreauba0b63d2009-09-20 08:09:44 +020092 if (!bytes)
93 return;
Willy Tarreau0abebcc2009-01-08 00:09:41 +010094 data_left = buf->l - buf->send_max;
Willy Tarreau91aa5772009-09-15 20:32:30 +020095 if (data_left >= bytes) {
96 buf->send_max += bytes;
Willy Tarreau2d028db2009-09-20 22:56:25 +020097 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreau91aa5772009-09-15 20:32:30 +020098 return;
99 }
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100100
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100101 buf->send_max += data_left;
Willy Tarreau2d028db2009-09-20 22:56:25 +0200102 if (buf->send_max)
103 buf->flags &= ~BF_OUT_EMPTY;
104
Willy Tarreau31971e52009-09-20 12:07:52 +0200105 if (buf->to_forward == BUF_INFINITE_FORWARD)
106 return;
107
108 buf->to_forward += bytes - data_left;
109 if (bytes == BUF_INFINITE_FORWARD)
110 buf->to_forward = bytes;
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100111}
112
Willy Tarreaue8a28bf2009-03-08 21:12:04 +0100113/* Schedule all remaining buffer data to be sent. send_max is not touched if it
114 * already covers those data. That permits doing a flush even after a forward,
115 * although not recommended.
116 */
117static inline void buffer_flush(struct buffer *buf)
118{
119 if (buf->send_max < buf->l)
120 buf->send_max = buf->l;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200121 if (buf->send_max)
122 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreaue8a28bf2009-03-08 21:12:04 +0100123}
124
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100125/* Erase any content from buffer <buf> and adjusts flags accordingly. Note
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100126 * that any spliced data is not affected since we may not have any access to
127 * it.
Willy Tarreaue393fe22008-08-16 22:18:07 +0200128 */
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100129static inline void buffer_erase(struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200130{
Willy Tarreauf890dc92008-12-13 21:12:26 +0100131 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +0100132 buf->to_forward = 0;
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100133 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200134 buf->l = 0;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200135 buf->flags &= ~(BF_FULL | BF_OUT_EMPTY);
136 if (!buf->pipe)
137 buf->flags |= BF_OUT_EMPTY;
138 if (!buf->max_len)
139 buf->flags |= BF_FULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200140}
141
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200142/* Cut the "tail" of the buffer, which means strip it to the length of unsent
143 * data only, and kill any remaining unsent data. Any scheduled forwarding is
144 * stopped. This is mainly to be used to send error messages after existing
145 * data.
146 */
147static inline void buffer_cut_tail(struct buffer *buf)
148{
149 if (!buf->send_max)
150 return buffer_erase(buf);
151
152 buf->to_forward = 0;
153 if (buf->l == buf->send_max)
154 return;
155
156 buf->l = buf->send_max;
157 buf->r = buf->w + buf->l;
158 if (buf->r >= buf->data + buf->size)
159 buf->r -= buf->size;
160 buf->lr = buf->r;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200161 buf->flags &= ~BF_FULL;
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200162 if (buf->l >= buf->max_len)
163 buf->flags |= BF_FULL;
164}
165
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200166/* marks the buffer as "shutdown" ASAP for reads */
167static inline void buffer_shutr_now(struct buffer *buf)
168{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100169 buf->flags |= BF_SHUTR_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200170}
171
172/* marks the buffer as "shutdown" ASAP for writes */
173static inline void buffer_shutw_now(struct buffer *buf)
174{
175 buf->flags |= BF_SHUTW_NOW;
176}
177
178/* marks the buffer as "shutdown" ASAP in both directions */
179static inline void buffer_abort(struct buffer *buf)
180{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100181 buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200182}
183
Willy Tarreau01bf8672008-12-07 18:03:29 +0100184/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
185 * flag is set, and the function called once. The function is responsible for
186 * clearing the hijack bit. It is possible that the function clears the flag
187 * during this first call.
188 */
189static inline void buffer_install_hijacker(struct session *s,
190 struct buffer *b,
191 void (*func)(struct session *, struct buffer *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200192{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100193 b->hijacker = func;
194 b->flags |= BF_HIJACK;
195 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200196}
197
Willy Tarreau01bf8672008-12-07 18:03:29 +0100198/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau72b179a2008-08-28 16:01:32 +0200199static inline void buffer_stop_hijack(struct buffer *buf)
200{
201 buf->flags &= ~BF_HIJACK;
202}
203
Willy Tarreau520d95e2009-09-19 21:04:57 +0200204/* allow the consumer to try to establish a new connection. */
205static inline void buffer_auto_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200206{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200207 buf->flags |= BF_AUTO_CONNECT;
Willy Tarreau3da77c52008-08-29 09:58:42 +0200208}
209
Willy Tarreau520d95e2009-09-19 21:04:57 +0200210/* prevent the consumer from trying to establish a new connection, and also
211 * disable auto shutdown forwarding.
212 */
213static inline void buffer_dont_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200214{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200215 buf->flags &= ~(BF_AUTO_CONNECT|BF_AUTO_CLOSE);
Willy Tarreau3da77c52008-08-29 09:58:42 +0200216}
217
Willy Tarreau520d95e2009-09-19 21:04:57 +0200218/* allow the producer to forward shutdown requests */
219static inline void buffer_auto_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100220{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200221 buf->flags |= BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100222}
223
Willy Tarreau520d95e2009-09-19 21:04:57 +0200224/* prevent the producer from forwarding shutdown requests */
225static inline void buffer_dont_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100226{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200227 buf->flags &= ~BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100228}
229
Willy Tarreaubaaee002006-06-26 02:48:02 +0200230/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200231static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200232{
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200233 if (buf->l == buf->size)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200234 return 0;
235 else if (buf->r >= buf->w)
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200236 return buf->data + buf->size - buf->r;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200237 else
238 return buf->w - buf->r;
239}
240
Willy Tarreaue393fe22008-08-16 22:18:07 +0200241/* sets the buffer read limit to <size> bytes, and adjusts the FULL
242 * flag accordingly.
243 */
244static inline void buffer_set_rlim(struct buffer *buf, int size)
245{
Willy Tarreau03d60bb2009-01-09 11:13:00 +0100246 buf->max_len = size;
Willy Tarreaue393fe22008-08-16 22:18:07 +0200247 if (buf->l < size)
248 buf->flags &= ~BF_FULL;
249 else
250 buf->flags |= BF_FULL;
251}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200252
253/*
254 * Tries to realign the given buffer, and returns how many bytes can be written
255 * there at once without overwriting anything.
256 */
257static inline int buffer_realign(struct buffer *buf)
258{
259 if (buf->l == 0) {
260 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100261 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200262 }
263 return buffer_max(buf);
264}
265
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200266/*
267 * Return the max amount of bytes that can be stuffed into the buffer at once.
268 * Note that this may be lower than the actual buffer size when the free space
269 * wraps after the end, so it's preferable to call this function again after
270 * writing. Also note that this function respects max_len.
271 */
272static inline int buffer_contig_space(struct buffer *buf)
273{
274 int ret;
275
276 if (buf->l == 0) {
277 buf->r = buf->w = buf->lr = buf->data;
278 ret = buf->max_len;
279 }
280 else if (buf->r > buf->w) {
281 ret = buf->data + buf->max_len - buf->r;
282 }
283 else {
284 ret = buf->w - buf->r;
285 if (ret > buf->max_len)
286 ret = buf->max_len;
287 }
288 return ret;
289}
290
Willy Tarreau4e33d862009-10-11 23:35:10 +0200291/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
292static inline int buffer_almost_full(struct buffer *buf)
293{
294 if (buffer_contig_space(buf) < buf->size / 4)
295 return 1;
296 return 0;
297}
298
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200299/*
300 * Return the max amount of bytes that can be read from the buffer at once.
301 * Note that this may be lower than the actual buffer length when the data
302 * wrap after the end, so it's preferable to call this function again after
303 * reading. Also note that this function respects the send_max limit.
304 */
305static inline int buffer_contig_data(struct buffer *buf)
306{
307 int ret;
308
309 if (!buf->send_max || !buf->l)
310 return 0;
311
312 if (buf->r > buf->w)
313 ret = buf->r - buf->w;
314 else
315 ret = buf->data + buf->size - buf->w;
316
317 /* limit the amount of outgoing data if required */
318 if (ret > buf->send_max)
319 ret = buf->send_max;
320
321 return ret;
322}
323
324/*
325 * Advance the buffer's read pointer by <len> bytes. This is useful when data
326 * have been read directly from the buffer. It is illegal to call this function
327 * with <len> causing a wrapping at the end of the buffer. It's the caller's
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200328 * responsibility to ensure that <len> is never larger than buf->send_max.
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200329 */
330static inline void buffer_skip(struct buffer *buf, int len)
331{
332 buf->w += len;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200333 if (buf->w >= buf->data + buf->size)
334 buf->w -= buf->size; /* wrap around the buffer */
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200335
336 buf->l -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200337 if (!buf->l)
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200338 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200339
340 if (buf->l < buf->max_len)
341 buf->flags &= ~BF_FULL;
342
343 buf->send_max -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200344 if (!buf->send_max && !buf->pipe)
345 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200346
347 /* notify that some data was written to the SI from the buffer */
348 buf->flags |= BF_WRITE_PARTIAL;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200349}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200350
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200351/*
352 * Return one char from the buffer. If the buffer is empty and closed, return -1.
353 * If the buffer is just empty, return -2. The buffer's pointer is not advanced,
354 * it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char.
355 * Also note that this function respects the send_max limit.
356 */
357static inline int buffer_si_peekchar(struct buffer *buf)
358{
359 if (buf->send_max)
360 return *buf->w;
361
362 if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW))
363 return -1;
364 else
365 return -2;
366}
367
Willy Tarreauc77e7612009-09-13 14:58:00 +0200368/* Try to write character <c> into buffer <buf> after length controls. This
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200369 * work like buffer_feed2(buf, &c, 1).
Willy Tarreauc77e7612009-09-13 14:58:00 +0200370 * Returns non-zero in case of success, 0 if the buffer was full.
371 * The send limit is automatically adjusted with the amount of data written.
372 */
373static inline int buffer_si_putchar(struct buffer *buf, char c)
374{
375 if (buf->flags & BF_FULL)
376 return 0;
377
Willy Tarreauc77e7612009-09-13 14:58:00 +0200378 *buf->r = c;
379
380 buf->l++;
381 if (buf->l >= buf->max_len)
382 buf->flags |= BF_FULL;
383
384 buf->r++;
385 if (buf->r - buf->data == buf->size)
386 buf->r -= buf->size;
387
Willy Tarreau31971e52009-09-20 12:07:52 +0200388 if (buf->to_forward >= 1) {
389 if (buf->to_forward != BUF_INFINITE_FORWARD)
390 buf->to_forward--;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200391 buf->send_max++;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200392 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200393 }
394
395 buf->total++;
396 return 1;
397}
398
Willy Tarreaubaaee002006-06-26 02:48:02 +0200399int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200400int buffer_feed2(struct buffer *buf, const char *str, int len);
Willy Tarreau36a5c532009-09-03 07:13:50 +0200401int buffer_si_putchar(struct buffer *buf, char c);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200402int buffer_si_peekline(struct buffer *buf, char *str, int len);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100403int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
404int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
405int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100406void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200407
Willy Tarreauaeac3192009-08-31 08:09:57 +0200408
409/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of success,
410 * -2 if it is larger than the buffer size, or the number of bytes available
411 * otherwise. If the chunk has been written, its size is automatically reset
412 * to zero. The send limit is automatically adjusted with the amount of data
413 * written.
414 */
415static inline int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
416{
417 int ret;
418
419 ret = buffer_write(buf, chunk->str, chunk->len);
420 if (ret == -1)
421 chunk->len = 0;
422 return ret;
423}
424
425/* Try to write chunk <chunk> into buffer <buf> after length controls. This is
426 * the equivalent of buffer_write_chunk() except that to_forward and send_max
427 * are updated and that max_len is respected. Returns -1 in case of success,
428 * -2 if it is larger than the buffer size, or the number of bytes available
429 * otherwise. If the chunk has been written, its size is automatically reset
430 * to zero. The send limit is automatically adjusted with the amount of data
431 * written.
432 */
433static inline int buffer_feed_chunk(struct buffer *buf, struct chunk *chunk)
434{
435 int ret;
436
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200437 ret = buffer_feed2(buf, chunk->str, chunk->len);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200438 if (ret == -1)
439 chunk->len = 0;
440 return ret;
441}
442
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200443/* Try to write string <str> into buffer <buf> after length controls. This is
444 * the equivalent of buffer_feed2() except that string length is measured by
445 * the function. Returns -1 in case of success, -2 if it is larger than the
446 * buffer size, or the number of bytes available otherwise. The send limit is
447 * automatically adjusted with the amount of data written.
448 */
449static inline int buffer_feed(struct buffer *buf, const char *str)
450{
451 return buffer_feed2(buf, str, strlen(str));
452}
453
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200454static inline void chunk_init(struct chunk *chk, char *str, size_t size) {
455 chk->str = str;
456 chk->len = 0;
457 chk->size = size;
458}
459
460/* report 0 in case of error, 1 if OK. */
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200461static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, int len) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200462
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200463 if (size && len > size)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200464 return 0;
465
466 chk->str = str;
467 chk->len = len;
468 chk->size = size;
469
470 return 1;
471}
472
473static inline void chunk_initstr(struct chunk *chk, char *str) {
474 chk->str = str;
475 chk->len = strlen(str);
476 chk->size = 0; /* mark it read-only */
477}
478
479static inline int chunk_strcpy(struct chunk *chk, const char *str) {
480 size_t len;
481
482 len = strlen(str);
483
484 if (unlikely(len > chk->size))
485 return 0;
486
487 chk->len = len;
488 memcpy(chk->str, str, len);
489
490 return 1;
491}
492
493int chunk_printf(struct chunk *chk, const char *fmt, ...)
494 __attribute__ ((format(printf, 2, 3)));
495
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +0200496int chunk_htmlencode(struct chunk *dst, struct chunk *src);
497int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
498
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200499static inline void chunk_reset(struct chunk *chk) {
500 chk->str = NULL;
501 chk->len = -1;
502 chk->size = 0;
503}
504
505static inline void chunk_destroy(struct chunk *chk) {
506
507 if (!chk->size)
508 return;
509
510 if (chk->str)
511 free(chk->str);
512
513 chunk_reset(chk);
514}
515
Willy Tarreau0f772532006-12-23 20:51:41 +0100516/*
517 * frees the destination chunk if already allocated, allocates a new string,
518 * and copies the source into it. The pointer to the destination string is
519 * returned, or NULL if the allocation fails or if any pointer is NULL..
520 */
521static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
522 if (!dst || !src || !src->str)
523 return NULL;
524 if (dst->str)
525 free(dst->str);
526 dst->len = src->len;
527 dst->str = (char *)malloc(dst->len);
528 memcpy(dst->str, src->str, dst->len);
529 return dst->str;
530}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200531
532#endif /* _PROTO_BUFFERS_H */
533
534/*
535 * Local variables:
536 * c-indent-level: 8
537 * c-basic-offset: 8
538 * End:
539 */