blob: c19a284fc94b93ffeae149bf7af38ef6dbc06f2f [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
Willy Tarreau7c3c5412009-12-13 15:53:05 +01002 * include/proto/buffers.h
3 * Buffer management definitions, macros and inline functions.
4 *
5 * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
6 *
7 * 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 */
Willy Tarreaubaaee002006-06-26 02:48:02 +020021
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>
Willy Tarreau7c3c5412009-12-13 15:53:05 +010035#include <types/global.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020036
Willy Tarreau7341d942007-05-13 19:56:02 +020037extern struct pool_head *pool2_buffer;
38
39/* perform minimal intializations, report 0 in case of error, 1 if OK. */
40int init_buffer();
41
Willy Tarreau7c3c5412009-12-13 15:53:05 +010042/* Initialize all fields in the buffer. The BF_OUT_EMPTY flags is set. */
Willy Tarreau54469402006-07-29 16:59:06 +020043static inline void buffer_init(struct buffer *buf)
44{
Willy Tarreauf890dc92008-12-13 21:12:26 +010045 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +010046 buf->to_forward = 0;
Willy Tarreaue393fe22008-08-16 22:18:07 +020047 buf->l = buf->total = 0;
Willy Tarreau3eba98a2009-01-25 13:56:13 +010048 buf->pipe = NULL;
Willy Tarreau2df28e82008-08-17 15:20:19 +020049 buf->analysers = 0;
Willy Tarreaufa7e1022008-10-19 07:30:41 +020050 buf->cons = NULL;
Willy Tarreauba0b63d2009-09-20 08:09:44 +020051 buf->flags = BF_OUT_EMPTY;
Willy Tarreau2df28e82008-08-17 15:20:19 +020052 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreau54469402006-07-29 16:59:06 +020053}
54
Willy Tarreau7c3c5412009-12-13 15:53:05 +010055/* Return the max number of bytes the buffer can contain so that once all the
56 * pending bytes are forwarded, the buffer still has global.tune.maxrewrite
57 * bytes free. The result sits between buf->size - maxrewrite and buf->size.
58 */
59static inline int buffer_max_len(struct buffer *buf)
60{
61 if (buf->to_forward == BUF_INFINITE_FORWARD ||
62 buf->to_forward + buf->send_max >= global.tune.maxrewrite)
63 return buf->size;
64 else
65 return buf->size - global.tune.maxrewrite + buf->to_forward + buf->send_max;
66}
67
Willy Tarreau2eb52f02008-09-04 09:14:08 +020068/* Check buffer timeouts, and set the corresponding flags. The
69 * likely/unlikely have been optimized for fastest normal path.
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010070 * The read/write timeouts are not set if there was activity on the buffer.
71 * That way, we don't have to update the timeout on every I/O. Note that the
72 * analyser timeout is always checked.
Willy Tarreau2eb52f02008-09-04 09:14:08 +020073 */
74static inline void buffer_check_timeouts(struct buffer *b)
75{
Willy Tarreau86491c32008-12-14 09:04:47 +010076 if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT|BF_READ_ACTIVITY|BF_READ_NOEXP))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020077 unlikely(tick_is_expired(b->rex, now_ms)))
78 b->flags |= BF_READ_TIMEOUT;
79
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010080 if (likely(!(b->flags & (BF_SHUTW|BF_WRITE_TIMEOUT|BF_WRITE_ACTIVITY))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020081 unlikely(tick_is_expired(b->wex, now_ms)))
82 b->flags |= BF_WRITE_TIMEOUT;
83
84 if (likely(!(b->flags & BF_ANA_TIMEOUT)) &&
85 unlikely(tick_is_expired(b->analyse_exp, now_ms)))
86 b->flags |= BF_ANA_TIMEOUT;
87}
88
Willy Tarreau0abebcc2009-01-08 00:09:41 +010089/* Schedule <bytes> more bytes to be forwarded by the buffer without notifying
90 * the task. Any pending data in the buffer is scheduled to be sent as well,
91 * in the limit of the number of bytes to forward. This must be the only method
92 * to use to schedule bytes to be sent. Directly touching ->to_forward will
93 * cause lockups when send_max goes down to zero if nobody is ready to push the
94 * remaining data.
95 */
Willy Tarreau31971e52009-09-20 12:07:52 +020096static inline void buffer_forward(struct buffer *buf, unsigned long bytes)
Willy Tarreau0abebcc2009-01-08 00:09:41 +010097{
Willy Tarreau31971e52009-09-20 12:07:52 +020098 unsigned long data_left;
Willy Tarreau0abebcc2009-01-08 00:09:41 +010099
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200100 if (!bytes)
101 return;
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100102 data_left = buf->l - buf->send_max;
Willy Tarreau91aa5772009-09-15 20:32:30 +0200103 if (data_left >= bytes) {
104 buf->send_max += bytes;
Willy Tarreau2d028db2009-09-20 22:56:25 +0200105 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreau91aa5772009-09-15 20:32:30 +0200106 return;
107 }
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100108
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100109 buf->send_max += data_left;
Willy Tarreau2d028db2009-09-20 22:56:25 +0200110 if (buf->send_max)
111 buf->flags &= ~BF_OUT_EMPTY;
112
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100113 if (buf->to_forward != BUF_INFINITE_FORWARD) {
114 buf->to_forward += bytes - data_left;
115 if (bytes == BUF_INFINITE_FORWARD)
116 buf->to_forward = bytes;
117 }
Willy Tarreau31971e52009-09-20 12:07:52 +0200118
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100119 if (buf->l < buffer_max_len(buf))
120 buf->flags &= ~BF_FULL;
121 else
122 buf->flags |= BF_FULL;
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100123}
124
Willy Tarreaue8a28bf2009-03-08 21:12:04 +0100125/* Schedule all remaining buffer data to be sent. send_max is not touched if it
126 * already covers those data. That permits doing a flush even after a forward,
127 * although not recommended.
128 */
129static inline void buffer_flush(struct buffer *buf)
130{
131 if (buf->send_max < buf->l)
132 buf->send_max = buf->l;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200133 if (buf->send_max)
134 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreaue8a28bf2009-03-08 21:12:04 +0100135}
136
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100137/* Erase any content from buffer <buf> and adjusts flags accordingly. Note
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100138 * that any spliced data is not affected since we may not have any access to
139 * it.
Willy Tarreaue393fe22008-08-16 22:18:07 +0200140 */
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100141static inline void buffer_erase(struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200142{
Willy Tarreauf890dc92008-12-13 21:12:26 +0100143 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +0100144 buf->to_forward = 0;
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100145 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200146 buf->l = 0;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200147 buf->flags &= ~(BF_FULL | BF_OUT_EMPTY);
148 if (!buf->pipe)
149 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200150}
151
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200152/* Cut the "tail" of the buffer, which means strip it to the length of unsent
153 * data only, and kill any remaining unsent data. Any scheduled forwarding is
154 * stopped. This is mainly to be used to send error messages after existing
155 * data.
156 */
157static inline void buffer_cut_tail(struct buffer *buf)
158{
159 if (!buf->send_max)
160 return buffer_erase(buf);
161
162 buf->to_forward = 0;
163 if (buf->l == buf->send_max)
164 return;
165
166 buf->l = buf->send_max;
167 buf->r = buf->w + buf->l;
168 if (buf->r >= buf->data + buf->size)
169 buf->r -= buf->size;
170 buf->lr = buf->r;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200171 buf->flags &= ~BF_FULL;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100172 if (buf->l >= buffer_max_len(buf))
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200173 buf->flags |= BF_FULL;
174}
175
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200176/* marks the buffer as "shutdown" ASAP for reads */
177static inline void buffer_shutr_now(struct buffer *buf)
178{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100179 buf->flags |= BF_SHUTR_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200180}
181
182/* marks the buffer as "shutdown" ASAP for writes */
183static inline void buffer_shutw_now(struct buffer *buf)
184{
185 buf->flags |= BF_SHUTW_NOW;
186}
187
188/* marks the buffer as "shutdown" ASAP in both directions */
189static inline void buffer_abort(struct buffer *buf)
190{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100191 buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200192}
193
Willy Tarreau01bf8672008-12-07 18:03:29 +0100194/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
195 * flag is set, and the function called once. The function is responsible for
196 * clearing the hijack bit. It is possible that the function clears the flag
197 * during this first call.
198 */
199static inline void buffer_install_hijacker(struct session *s,
200 struct buffer *b,
201 void (*func)(struct session *, struct buffer *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200202{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100203 b->hijacker = func;
204 b->flags |= BF_HIJACK;
205 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200206}
207
Willy Tarreau01bf8672008-12-07 18:03:29 +0100208/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau72b179a2008-08-28 16:01:32 +0200209static inline void buffer_stop_hijack(struct buffer *buf)
210{
211 buf->flags &= ~BF_HIJACK;
212}
213
Willy Tarreau520d95e2009-09-19 21:04:57 +0200214/* allow the consumer to try to establish a new connection. */
215static inline void buffer_auto_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200216{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200217 buf->flags |= BF_AUTO_CONNECT;
Willy Tarreau3da77c52008-08-29 09:58:42 +0200218}
219
Willy Tarreau520d95e2009-09-19 21:04:57 +0200220/* prevent the consumer from trying to establish a new connection, and also
221 * disable auto shutdown forwarding.
222 */
223static inline void buffer_dont_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200224{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200225 buf->flags &= ~(BF_AUTO_CONNECT|BF_AUTO_CLOSE);
Willy Tarreau3da77c52008-08-29 09:58:42 +0200226}
227
Willy Tarreau520d95e2009-09-19 21:04:57 +0200228/* allow the producer to forward shutdown requests */
229static inline void buffer_auto_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100230{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200231 buf->flags |= BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100232}
233
Willy Tarreau520d95e2009-09-19 21:04:57 +0200234/* prevent the producer from forwarding shutdown requests */
235static inline void buffer_dont_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100236{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200237 buf->flags &= ~BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100238}
239
Willy Tarreaubaaee002006-06-26 02:48:02 +0200240/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200241static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200242{
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200243 if (buf->l == buf->size)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200244 return 0;
245 else if (buf->r >= buf->w)
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200246 return buf->data + buf->size - buf->r;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200247 else
248 return buf->w - buf->r;
249}
250
Willy Tarreaubaaee002006-06-26 02:48:02 +0200251/*
252 * Tries to realign the given buffer, and returns how many bytes can be written
253 * there at once without overwriting anything.
254 */
255static inline int buffer_realign(struct buffer *buf)
256{
257 if (buf->l == 0) {
258 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100259 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200260 }
261 return buffer_max(buf);
262}
263
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200264/*
265 * Return the max amount of bytes that can be stuffed into the buffer at once.
266 * Note that this may be lower than the actual buffer size when the free space
267 * wraps after the end, so it's preferable to call this function again after
268 * writing. Also note that this function respects max_len.
269 */
270static inline int buffer_contig_space(struct buffer *buf)
271{
272 int ret;
273
274 if (buf->l == 0) {
275 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100276 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200277 }
278 else if (buf->r > buf->w) {
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100279 ret = buf->data + buffer_max_len(buf) - buf->r;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200280 }
281 else {
282 ret = buf->w - buf->r;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100283 if (ret > buffer_max_len(buf))
284 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200285 }
286 return ret;
287}
288
Willy Tarreau4e33d862009-10-11 23:35:10 +0200289/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
290static inline int buffer_almost_full(struct buffer *buf)
291{
292 if (buffer_contig_space(buf) < buf->size / 4)
293 return 1;
294 return 0;
295}
296
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200297/*
298 * Return the max amount of bytes that can be read from the buffer at once.
299 * Note that this may be lower than the actual buffer length when the data
300 * wrap after the end, so it's preferable to call this function again after
301 * reading. Also note that this function respects the send_max limit.
302 */
303static inline int buffer_contig_data(struct buffer *buf)
304{
305 int ret;
306
307 if (!buf->send_max || !buf->l)
308 return 0;
309
310 if (buf->r > buf->w)
311 ret = buf->r - buf->w;
312 else
313 ret = buf->data + buf->size - buf->w;
314
315 /* limit the amount of outgoing data if required */
316 if (ret > buf->send_max)
317 ret = buf->send_max;
318
319 return ret;
320}
321
322/*
323 * Advance the buffer's read pointer by <len> bytes. This is useful when data
324 * have been read directly from the buffer. It is illegal to call this function
325 * with <len> causing a wrapping at the end of the buffer. It's the caller's
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200326 * responsibility to ensure that <len> is never larger than buf->send_max.
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200327 */
328static inline void buffer_skip(struct buffer *buf, int len)
329{
330 buf->w += len;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200331 if (buf->w >= buf->data + buf->size)
332 buf->w -= buf->size; /* wrap around the buffer */
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200333
334 buf->l -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200335 if (!buf->l)
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200336 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200337
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100338 if (buf->l < buffer_max_len(buf))
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200339 buf->flags &= ~BF_FULL;
340
341 buf->send_max -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200342 if (!buf->send_max && !buf->pipe)
343 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200344
345 /* notify that some data was written to the SI from the buffer */
346 buf->flags |= BF_WRITE_PARTIAL;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200347}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200348
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200349/*
350 * Return one char from the buffer. If the buffer is empty and closed, return -1.
351 * If the buffer is just empty, return -2. The buffer's pointer is not advanced,
352 * it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char.
353 * Also note that this function respects the send_max limit.
354 */
355static inline int buffer_si_peekchar(struct buffer *buf)
356{
357 if (buf->send_max)
358 return *buf->w;
359
360 if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW))
361 return -1;
362 else
363 return -2;
364}
365
Willy Tarreauc77e7612009-09-13 14:58:00 +0200366/* Try to write character <c> into buffer <buf> after length controls. This
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200367 * work like buffer_feed2(buf, &c, 1).
Willy Tarreauc77e7612009-09-13 14:58:00 +0200368 * Returns non-zero in case of success, 0 if the buffer was full.
369 * The send limit is automatically adjusted with the amount of data written.
370 */
371static inline int buffer_si_putchar(struct buffer *buf, char c)
372{
373 if (buf->flags & BF_FULL)
374 return 0;
375
Willy Tarreauc77e7612009-09-13 14:58:00 +0200376 *buf->r = c;
377
378 buf->l++;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100379 if (buf->l >= buffer_max_len(buf))
Willy Tarreauc77e7612009-09-13 14:58:00 +0200380 buf->flags |= BF_FULL;
381
382 buf->r++;
383 if (buf->r - buf->data == buf->size)
384 buf->r -= buf->size;
385
Willy Tarreau31971e52009-09-20 12:07:52 +0200386 if (buf->to_forward >= 1) {
387 if (buf->to_forward != BUF_INFINITE_FORWARD)
388 buf->to_forward--;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200389 buf->send_max++;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200390 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200391 }
392
393 buf->total++;
394 return 1;
395}
396
Willy Tarreaubaaee002006-06-26 02:48:02 +0200397int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200398int buffer_feed2(struct buffer *buf, const char *str, int len);
Willy Tarreau36a5c532009-09-03 07:13:50 +0200399int buffer_si_putchar(struct buffer *buf, char c);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200400int buffer_si_peekline(struct buffer *buf, char *str, int len);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100401int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
402int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
403int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100404void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200405
Willy Tarreauaeac3192009-08-31 08:09:57 +0200406
407/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of success,
408 * -2 if it is larger than the buffer size, or the number of bytes available
409 * otherwise. If the chunk has been written, its size is automatically reset
410 * to zero. The send limit is automatically adjusted with the amount of data
411 * written.
412 */
413static inline int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
414{
415 int ret;
416
417 ret = buffer_write(buf, chunk->str, chunk->len);
418 if (ret == -1)
419 chunk->len = 0;
420 return ret;
421}
422
423/* Try to write chunk <chunk> into buffer <buf> after length controls. This is
424 * the equivalent of buffer_write_chunk() except that to_forward and send_max
425 * are updated and that max_len is respected. Returns -1 in case of success,
426 * -2 if it is larger than the buffer size, or the number of bytes available
427 * otherwise. If the chunk has been written, its size is automatically reset
428 * to zero. The send limit is automatically adjusted with the amount of data
429 * written.
430 */
431static inline int buffer_feed_chunk(struct buffer *buf, struct chunk *chunk)
432{
433 int ret;
434
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200435 ret = buffer_feed2(buf, chunk->str, chunk->len);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200436 if (ret == -1)
437 chunk->len = 0;
438 return ret;
439}
440
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200441/* Try to write string <str> into buffer <buf> after length controls. This is
442 * the equivalent of buffer_feed2() except that string length is measured by
443 * the function. Returns -1 in case of success, -2 if it is larger than the
444 * buffer size, or the number of bytes available otherwise. The send limit is
445 * automatically adjusted with the amount of data written.
446 */
447static inline int buffer_feed(struct buffer *buf, const char *str)
448{
449 return buffer_feed2(buf, str, strlen(str));
450}
451
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200452static inline void chunk_init(struct chunk *chk, char *str, size_t size) {
453 chk->str = str;
454 chk->len = 0;
455 chk->size = size;
456}
457
458/* report 0 in case of error, 1 if OK. */
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200459static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, int len) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200460
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200461 if (size && len > size)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200462 return 0;
463
464 chk->str = str;
465 chk->len = len;
466 chk->size = size;
467
468 return 1;
469}
470
471static inline void chunk_initstr(struct chunk *chk, char *str) {
472 chk->str = str;
473 chk->len = strlen(str);
474 chk->size = 0; /* mark it read-only */
475}
476
477static inline int chunk_strcpy(struct chunk *chk, const char *str) {
478 size_t len;
479
480 len = strlen(str);
481
482 if (unlikely(len > chk->size))
483 return 0;
484
485 chk->len = len;
486 memcpy(chk->str, str, len);
487
488 return 1;
489}
490
491int chunk_printf(struct chunk *chk, const char *fmt, ...)
492 __attribute__ ((format(printf, 2, 3)));
493
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +0200494int chunk_htmlencode(struct chunk *dst, struct chunk *src);
495int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
496
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200497static inline void chunk_reset(struct chunk *chk) {
498 chk->str = NULL;
499 chk->len = -1;
500 chk->size = 0;
501}
502
503static inline void chunk_destroy(struct chunk *chk) {
504
505 if (!chk->size)
506 return;
507
508 if (chk->str)
509 free(chk->str);
510
511 chunk_reset(chk);
512}
513
Willy Tarreau0f772532006-12-23 20:51:41 +0100514/*
515 * frees the destination chunk if already allocated, allocates a new string,
516 * and copies the source into it. The pointer to the destination string is
517 * returned, or NULL if the allocation fails or if any pointer is NULL..
518 */
519static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
520 if (!dst || !src || !src->str)
521 return NULL;
522 if (dst->str)
523 free(dst->str);
524 dst->len = src->len;
525 dst->str = (char *)malloc(dst->len);
526 memcpy(dst->str, src->str, dst->len);
527 return dst->str;
528}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200529
530#endif /* _PROTO_BUFFERS_H */
531
532/*
533 * Local variables:
534 * c-indent-level: 8
535 * c-basic-offset: 8
536 * End:
537 */