blob: cec7b02fbbf9968e48eb6e0fbc44fdf7c94e6534 [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
291/*
292 * Return the max amount of bytes that can be read from the buffer at once.
293 * Note that this may be lower than the actual buffer length when the data
294 * wrap after the end, so it's preferable to call this function again after
295 * reading. Also note that this function respects the send_max limit.
296 */
297static inline int buffer_contig_data(struct buffer *buf)
298{
299 int ret;
300
301 if (!buf->send_max || !buf->l)
302 return 0;
303
304 if (buf->r > buf->w)
305 ret = buf->r - buf->w;
306 else
307 ret = buf->data + buf->size - buf->w;
308
309 /* limit the amount of outgoing data if required */
310 if (ret > buf->send_max)
311 ret = buf->send_max;
312
313 return ret;
314}
315
316/*
317 * Advance the buffer's read pointer by <len> bytes. This is useful when data
318 * have been read directly from the buffer. It is illegal to call this function
319 * with <len> causing a wrapping at the end of the buffer. It's the caller's
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200320 * responsibility to ensure that <len> is never larger than buf->send_max.
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200321 */
322static inline void buffer_skip(struct buffer *buf, int len)
323{
324 buf->w += len;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200325 if (buf->w >= buf->data + buf->size)
326 buf->w -= buf->size; /* wrap around the buffer */
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200327
328 buf->l -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200329 if (!buf->l)
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200330 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200331
332 if (buf->l < buf->max_len)
333 buf->flags &= ~BF_FULL;
334
335 buf->send_max -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200336 if (!buf->send_max && !buf->pipe)
337 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200338
339 /* notify that some data was written to the SI from the buffer */
340 buf->flags |= BF_WRITE_PARTIAL;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200341}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200342
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200343/*
344 * Return one char from the buffer. If the buffer is empty and closed, return -1.
345 * If the buffer is just empty, return -2. The buffer's pointer is not advanced,
346 * it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char.
347 * Also note that this function respects the send_max limit.
348 */
349static inline int buffer_si_peekchar(struct buffer *buf)
350{
351 if (buf->send_max)
352 return *buf->w;
353
354 if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW))
355 return -1;
356 else
357 return -2;
358}
359
Willy Tarreauc77e7612009-09-13 14:58:00 +0200360/* Try to write character <c> into buffer <buf> after length controls. This
361 * work like buffer_feed(buf, &c, 1).
362 * Returns non-zero in case of success, 0 if the buffer was full.
363 * The send limit is automatically adjusted with the amount of data written.
364 */
365static inline int buffer_si_putchar(struct buffer *buf, char c)
366{
367 if (buf->flags & BF_FULL)
368 return 0;
369
Willy Tarreauc77e7612009-09-13 14:58:00 +0200370 *buf->r = c;
371
372 buf->l++;
373 if (buf->l >= buf->max_len)
374 buf->flags |= BF_FULL;
375
376 buf->r++;
377 if (buf->r - buf->data == buf->size)
378 buf->r -= buf->size;
379
Willy Tarreau31971e52009-09-20 12:07:52 +0200380 if (buf->to_forward >= 1) {
381 if (buf->to_forward != BUF_INFINITE_FORWARD)
382 buf->to_forward--;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200383 buf->send_max++;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200384 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200385 }
386
387 buf->total++;
388 return 1;
389}
390
Willy Tarreaubaaee002006-06-26 02:48:02 +0200391int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200392int buffer_feed(struct buffer *buf, const char *str, int len);
Willy Tarreau36a5c532009-09-03 07:13:50 +0200393int buffer_si_putchar(struct buffer *buf, char c);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200394int buffer_si_peekline(struct buffer *buf, char *str, int len);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100395int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
396int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
397int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100398void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200399
Willy Tarreauaeac3192009-08-31 08:09:57 +0200400
401/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of success,
402 * -2 if it is larger than the buffer size, or the number of bytes available
403 * otherwise. If the chunk has been written, its size is automatically reset
404 * to zero. The send limit is automatically adjusted with the amount of data
405 * written.
406 */
407static inline int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
408{
409 int ret;
410
411 ret = buffer_write(buf, chunk->str, chunk->len);
412 if (ret == -1)
413 chunk->len = 0;
414 return ret;
415}
416
417/* Try to write chunk <chunk> into buffer <buf> after length controls. This is
418 * the equivalent of buffer_write_chunk() except that to_forward and send_max
419 * are updated and that max_len is respected. Returns -1 in case of success,
420 * -2 if it is larger than the buffer size, or the number of bytes available
421 * otherwise. If the chunk has been written, its size is automatically reset
422 * to zero. The send limit is automatically adjusted with the amount of data
423 * written.
424 */
425static inline int buffer_feed_chunk(struct buffer *buf, struct chunk *chunk)
426{
427 int ret;
428
429 ret = buffer_feed(buf, chunk->str, chunk->len);
430 if (ret == -1)
431 chunk->len = 0;
432 return ret;
433}
434
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200435static inline void chunk_init(struct chunk *chk, char *str, size_t size) {
436 chk->str = str;
437 chk->len = 0;
438 chk->size = size;
439}
440
441/* report 0 in case of error, 1 if OK. */
442static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, size_t len) {
443
444 if (len > size)
445 return 0;
446
447 chk->str = str;
448 chk->len = len;
449 chk->size = size;
450
451 return 1;
452}
453
454static inline void chunk_initstr(struct chunk *chk, char *str) {
455 chk->str = str;
456 chk->len = strlen(str);
457 chk->size = 0; /* mark it read-only */
458}
459
460static inline int chunk_strcpy(struct chunk *chk, const char *str) {
461 size_t len;
462
463 len = strlen(str);
464
465 if (unlikely(len > chk->size))
466 return 0;
467
468 chk->len = len;
469 memcpy(chk->str, str, len);
470
471 return 1;
472}
473
474int chunk_printf(struct chunk *chk, const char *fmt, ...)
475 __attribute__ ((format(printf, 2, 3)));
476
477static inline void chunk_reset(struct chunk *chk) {
478 chk->str = NULL;
479 chk->len = -1;
480 chk->size = 0;
481}
482
483static inline void chunk_destroy(struct chunk *chk) {
484
485 if (!chk->size)
486 return;
487
488 if (chk->str)
489 free(chk->str);
490
491 chunk_reset(chk);
492}
493
Willy Tarreau0f772532006-12-23 20:51:41 +0100494/*
495 * frees the destination chunk if already allocated, allocates a new string,
496 * and copies the source into it. The pointer to the destination string is
497 * returned, or NULL if the allocation fails or if any pointer is NULL..
498 */
499static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
500 if (!dst || !src || !src->str)
501 return NULL;
502 if (dst->str)
503 free(dst->str);
504 dst->len = src->len;
505 dst->str = (char *)malloc(dst->len);
506 memcpy(dst->str, src->str, dst->len);
507 return dst->str;
508}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200509
510#endif /* _PROTO_BUFFERS_H */
511
512/*
513 * Local variables:
514 * c-indent-level: 8
515 * c-basic-offset: 8
516 * End:
517 */