blob: e046f39276c0ffb6c02e8b3076f1f903f482bc41 [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 Tarreaud21e01c2009-12-27 15:45:38 +0100176/* Cut the <n> next unsent bytes of the buffer. The caller must ensure that <n>
177 * is smaller than the actual buffer's length. This is mainly used to remove
178 * empty lines at the beginning of a request or a response.
179 */
180static inline void buffer_ignore(struct buffer *buf, int n)
181{
182 buf->l -= n;
183 buf->w += n;
184 if (buf->w >= buf->data + buf->size)
185 buf->w -= buf->size;
186 buf->flags &= ~BF_FULL;
187 if (buf->l >= buffer_max_len(buf))
188 buf->flags |= BF_FULL;
189}
190
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200191/* marks the buffer as "shutdown" ASAP for reads */
192static inline void buffer_shutr_now(struct buffer *buf)
193{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100194 buf->flags |= BF_SHUTR_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200195}
196
197/* marks the buffer as "shutdown" ASAP for writes */
198static inline void buffer_shutw_now(struct buffer *buf)
199{
200 buf->flags |= BF_SHUTW_NOW;
201}
202
203/* marks the buffer as "shutdown" ASAP in both directions */
204static inline void buffer_abort(struct buffer *buf)
205{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100206 buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200207}
208
Willy Tarreau01bf8672008-12-07 18:03:29 +0100209/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
210 * flag is set, and the function called once. The function is responsible for
211 * clearing the hijack bit. It is possible that the function clears the flag
212 * during this first call.
213 */
214static inline void buffer_install_hijacker(struct session *s,
215 struct buffer *b,
216 void (*func)(struct session *, struct buffer *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200217{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100218 b->hijacker = func;
219 b->flags |= BF_HIJACK;
220 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200221}
222
Willy Tarreau01bf8672008-12-07 18:03:29 +0100223/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau72b179a2008-08-28 16:01:32 +0200224static inline void buffer_stop_hijack(struct buffer *buf)
225{
226 buf->flags &= ~BF_HIJACK;
227}
228
Willy Tarreau520d95e2009-09-19 21:04:57 +0200229/* allow the consumer to try to establish a new connection. */
230static inline void buffer_auto_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200231{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200232 buf->flags |= BF_AUTO_CONNECT;
Willy Tarreau3da77c52008-08-29 09:58:42 +0200233}
234
Willy Tarreau520d95e2009-09-19 21:04:57 +0200235/* prevent the consumer from trying to establish a new connection, and also
236 * disable auto shutdown forwarding.
237 */
238static inline void buffer_dont_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200239{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200240 buf->flags &= ~(BF_AUTO_CONNECT|BF_AUTO_CLOSE);
Willy Tarreau3da77c52008-08-29 09:58:42 +0200241}
242
Willy Tarreau520d95e2009-09-19 21:04:57 +0200243/* allow the producer to forward shutdown requests */
244static inline void buffer_auto_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100245{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200246 buf->flags |= BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100247}
248
Willy Tarreau520d95e2009-09-19 21:04:57 +0200249/* prevent the producer from forwarding shutdown requests */
250static inline void buffer_dont_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100251{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200252 buf->flags &= ~BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100253}
254
Willy Tarreau90deb182010-01-07 00:20:41 +0100255/* allow the producer to read / poll the input */
256static inline void buffer_auto_read(struct buffer *buf)
257{
258 buf->flags &= ~BF_DONT_READ;
259}
260
261/* prevent the producer from read / poll the input */
262static inline void buffer_dont_read(struct buffer *buf)
263{
264 buf->flags |= BF_DONT_READ;
265}
266
Willy Tarreaubaaee002006-06-26 02:48:02 +0200267/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200268static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200269{
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200270 if (buf->l == buf->size)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200271 return 0;
272 else if (buf->r >= buf->w)
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200273 return buf->data + buf->size - buf->r;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200274 else
275 return buf->w - buf->r;
276}
277
Willy Tarreaubaaee002006-06-26 02:48:02 +0200278/*
279 * Tries to realign the given buffer, and returns how many bytes can be written
280 * there at once without overwriting anything.
281 */
282static inline int buffer_realign(struct buffer *buf)
283{
284 if (buf->l == 0) {
285 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100286 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200287 }
288 return buffer_max(buf);
289}
290
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200291/*
292 * Return the max amount of bytes that can be stuffed into the buffer at once.
293 * Note that this may be lower than the actual buffer size when the free space
294 * wraps after the end, so it's preferable to call this function again after
295 * writing. Also note that this function respects max_len.
296 */
297static inline int buffer_contig_space(struct buffer *buf)
298{
299 int ret;
300
301 if (buf->l == 0) {
302 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100303 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200304 }
305 else if (buf->r > buf->w) {
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100306 ret = buf->data + buffer_max_len(buf) - buf->r;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200307 }
308 else {
309 ret = buf->w - buf->r;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100310 if (ret > buffer_max_len(buf))
311 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200312 }
313 return ret;
314}
315
Willy Tarreau4e33d862009-10-11 23:35:10 +0200316/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
317static inline int buffer_almost_full(struct buffer *buf)
318{
319 if (buffer_contig_space(buf) < buf->size / 4)
320 return 1;
321 return 0;
322}
323
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200324/*
325 * Return the max amount of bytes that can be read from the buffer at once.
326 * Note that this may be lower than the actual buffer length when the data
327 * wrap after the end, so it's preferable to call this function again after
328 * reading. Also note that this function respects the send_max limit.
329 */
330static inline int buffer_contig_data(struct buffer *buf)
331{
332 int ret;
333
334 if (!buf->send_max || !buf->l)
335 return 0;
336
337 if (buf->r > buf->w)
338 ret = buf->r - buf->w;
339 else
340 ret = buf->data + buf->size - buf->w;
341
342 /* limit the amount of outgoing data if required */
343 if (ret > buf->send_max)
344 ret = buf->send_max;
345
346 return ret;
347}
348
349/*
350 * Advance the buffer's read pointer by <len> bytes. This is useful when data
351 * have been read directly from the buffer. It is illegal to call this function
352 * with <len> causing a wrapping at the end of the buffer. It's the caller's
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200353 * responsibility to ensure that <len> is never larger than buf->send_max.
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200354 */
355static inline void buffer_skip(struct buffer *buf, int len)
356{
357 buf->w += len;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200358 if (buf->w >= buf->data + buf->size)
359 buf->w -= buf->size; /* wrap around the buffer */
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200360
361 buf->l -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200362 if (!buf->l)
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200363 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200364
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100365 if (buf->l < buffer_max_len(buf))
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200366 buf->flags &= ~BF_FULL;
367
368 buf->send_max -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200369 if (!buf->send_max && !buf->pipe)
370 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200371
372 /* notify that some data was written to the SI from the buffer */
373 buf->flags |= BF_WRITE_PARTIAL;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200374}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200375
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200376/*
377 * Return one char from the buffer. If the buffer is empty and closed, return -1.
378 * If the buffer is just empty, return -2. The buffer's pointer is not advanced,
379 * it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char.
380 * Also note that this function respects the send_max limit.
381 */
382static inline int buffer_si_peekchar(struct buffer *buf)
383{
384 if (buf->send_max)
385 return *buf->w;
386
387 if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW))
388 return -1;
389 else
390 return -2;
391}
392
Willy Tarreauc77e7612009-09-13 14:58:00 +0200393/* Try to write character <c> into buffer <buf> after length controls. This
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200394 * work like buffer_feed2(buf, &c, 1).
Willy Tarreauc77e7612009-09-13 14:58:00 +0200395 * Returns non-zero in case of success, 0 if the buffer was full.
396 * The send limit is automatically adjusted with the amount of data written.
397 */
398static inline int buffer_si_putchar(struct buffer *buf, char c)
399{
400 if (buf->flags & BF_FULL)
401 return 0;
402
Willy Tarreauc77e7612009-09-13 14:58:00 +0200403 *buf->r = c;
404
405 buf->l++;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100406 if (buf->l >= buffer_max_len(buf))
Willy Tarreauc77e7612009-09-13 14:58:00 +0200407 buf->flags |= BF_FULL;
408
409 buf->r++;
410 if (buf->r - buf->data == buf->size)
411 buf->r -= buf->size;
412
Willy Tarreau31971e52009-09-20 12:07:52 +0200413 if (buf->to_forward >= 1) {
414 if (buf->to_forward != BUF_INFINITE_FORWARD)
415 buf->to_forward--;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200416 buf->send_max++;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200417 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200418 }
419
420 buf->total++;
421 return 1;
422}
423
Willy Tarreaubaaee002006-06-26 02:48:02 +0200424int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200425int buffer_feed2(struct buffer *buf, const char *str, int len);
Willy Tarreau36a5c532009-09-03 07:13:50 +0200426int buffer_si_putchar(struct buffer *buf, char c);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200427int buffer_si_peekline(struct buffer *buf, char *str, int len);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100428int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
429int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
430int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100431void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200432
Willy Tarreauaeac3192009-08-31 08:09:57 +0200433
434/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of success,
435 * -2 if it is larger than the buffer size, or the number of bytes available
436 * otherwise. If the chunk has been written, its size is automatically reset
437 * to zero. The send limit is automatically adjusted with the amount of data
438 * written.
439 */
440static inline int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
441{
442 int ret;
443
444 ret = buffer_write(buf, chunk->str, chunk->len);
445 if (ret == -1)
446 chunk->len = 0;
447 return ret;
448}
449
450/* Try to write chunk <chunk> into buffer <buf> after length controls. This is
451 * the equivalent of buffer_write_chunk() except that to_forward and send_max
452 * are updated and that max_len is respected. Returns -1 in case of success,
453 * -2 if it is larger than the buffer size, or the number of bytes available
454 * otherwise. If the chunk has been written, its size is automatically reset
455 * to zero. The send limit is automatically adjusted with the amount of data
456 * written.
457 */
458static inline int buffer_feed_chunk(struct buffer *buf, struct chunk *chunk)
459{
460 int ret;
461
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200462 ret = buffer_feed2(buf, chunk->str, chunk->len);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200463 if (ret == -1)
464 chunk->len = 0;
465 return ret;
466}
467
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200468/* Try to write string <str> into buffer <buf> after length controls. This is
469 * the equivalent of buffer_feed2() except that string length is measured by
470 * the function. Returns -1 in case of success, -2 if it is larger than the
471 * buffer size, or the number of bytes available otherwise. The send limit is
472 * automatically adjusted with the amount of data written.
473 */
474static inline int buffer_feed(struct buffer *buf, const char *str)
475{
476 return buffer_feed2(buf, str, strlen(str));
477}
478
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200479static inline void chunk_init(struct chunk *chk, char *str, size_t size) {
480 chk->str = str;
481 chk->len = 0;
482 chk->size = size;
483}
484
485/* report 0 in case of error, 1 if OK. */
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200486static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, int len) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200487
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200488 if (size && len > size)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200489 return 0;
490
491 chk->str = str;
492 chk->len = len;
493 chk->size = size;
494
495 return 1;
496}
497
498static inline void chunk_initstr(struct chunk *chk, char *str) {
499 chk->str = str;
500 chk->len = strlen(str);
501 chk->size = 0; /* mark it read-only */
502}
503
504static inline int chunk_strcpy(struct chunk *chk, const char *str) {
505 size_t len;
506
507 len = strlen(str);
508
509 if (unlikely(len > chk->size))
510 return 0;
511
512 chk->len = len;
513 memcpy(chk->str, str, len);
514
515 return 1;
516}
517
518int chunk_printf(struct chunk *chk, const char *fmt, ...)
519 __attribute__ ((format(printf, 2, 3)));
520
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +0200521int chunk_htmlencode(struct chunk *dst, struct chunk *src);
522int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
523
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200524static inline void chunk_reset(struct chunk *chk) {
525 chk->str = NULL;
526 chk->len = -1;
527 chk->size = 0;
528}
529
530static inline void chunk_destroy(struct chunk *chk) {
531
532 if (!chk->size)
533 return;
534
535 if (chk->str)
536 free(chk->str);
537
538 chunk_reset(chk);
539}
540
Willy Tarreau0f772532006-12-23 20:51:41 +0100541/*
542 * frees the destination chunk if already allocated, allocates a new string,
543 * and copies the source into it. The pointer to the destination string is
544 * returned, or NULL if the allocation fails or if any pointer is NULL..
545 */
546static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
547 if (!dst || !src || !src->str)
548 return NULL;
549 if (dst->str)
550 free(dst->str);
551 dst->len = src->len;
552 dst->str = (char *)malloc(dst->len);
553 memcpy(dst->str, src->str, dst->len);
554 return dst->str;
555}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200556
557#endif /* _PROTO_BUFFERS_H */
558
559/*
560 * Local variables:
561 * c-indent-level: 8
562 * c-basic-offset: 8
563 * End:
564 */