serf_bucket_util.h revision 253895
1353944Sdim/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
2353944Sdim *
3353944Sdim * Licensed under the Apache License, Version 2.0 (the "License");
4353944Sdim * you may not use this file except in compliance with the License.
5353944Sdim * You may obtain a copy of the License at
6353944Sdim *
7353944Sdim *     http://www.apache.org/licenses/LICENSE-2.0
8353944Sdim *
9353944Sdim * Unless required by applicable law or agreed to in writing, software
10353944Sdim * distributed under the License is distributed on an "AS IS" BASIS,
11353944Sdim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12353944Sdim * See the License for the specific language governing permissions and
13353944Sdim * limitations under the License.
14353944Sdim */
15353944Sdim
16353944Sdim#ifndef SERF_BUCKET_UTIL_H
17353944Sdim#define SERF_BUCKET_UTIL_H
18353944Sdim
19353944Sdim/**
20353944Sdim * @file serf_bucket_util.h
21353944Sdim * @brief This header defines a set of functions and other utilities
22353944Sdim * for implementing buckets. It is not needed by users of the bucket
23353944Sdim * system.
24353944Sdim */
25353944Sdim
26353944Sdim#include "serf.h"
27353944Sdim
28353944Sdim#ifdef __cplusplus
29353944Sdimextern "C" {
30353944Sdim#endif
31353944Sdim
32353944Sdim
33353944Sdim/**
34353944Sdim * Basic bucket creation function.
35353944Sdim *
36353944Sdim * This function will create a bucket of @a type, allocating the necessary
37353944Sdim * memory from @a allocator. The @a data bucket-private information will
38353944Sdim * be stored into the bucket.
39353944Sdim */
40353944Sdimserf_bucket_t *serf_bucket_create(
41353944Sdim    const serf_bucket_type_t *type,
42353944Sdim    serf_bucket_alloc_t *allocator,
43353944Sdim    void *data);
44353944Sdim
45353944Sdim/**
46353944Sdim * Default implementation of the @see read_iovec functionality.
47353944Sdim *
48353944Sdim * This function will use the @see read function to get a block of memory,
49353944Sdim * then return it in the iovec.
50353944Sdim */
51353944Sdimapr_status_t serf_default_read_iovec(
52353944Sdim    serf_bucket_t *bucket,
53353944Sdim    apr_size_t requested,
54353944Sdim    int vecs_size,
55353944Sdim    struct iovec *vecs,
56353944Sdim    int *vecs_used);
57353944Sdim
58353944Sdim/**
59353944Sdim * Default implementation of the @see read_for_sendfile functionality.
60353944Sdim *
61353944Sdim * This function will use the @see read function to get a block of memory,
62353944Sdim * then return it as a header. No file will be returned.
63353944Sdim */
64353944Sdimapr_status_t serf_default_read_for_sendfile(
65353944Sdim    serf_bucket_t *bucket,
66353944Sdim    apr_size_t requested,
67353944Sdim    apr_hdtr_t *hdtr,
68353944Sdim    apr_file_t **file,
69353944Sdim    apr_off_t *offset,
70353944Sdim    apr_size_t *len);
71353944Sdim
72353944Sdim/**
73353944Sdim * Default implementation of the @see read_bucket functionality.
74353944Sdim *
75353944Sdim * This function will always return NULL, indicating that the @a type
76353944Sdim * of bucket cannot be found within @a bucket.
77353944Sdim */
78353944Sdimserf_bucket_t *serf_default_read_bucket(
79353944Sdim    serf_bucket_t *bucket,
80353944Sdim    const serf_bucket_type_t *type);
81353944Sdim
82353944Sdim/**
83353944Sdim * Default implementation of the @see destroy functionality.
84353944Sdim *
85353944Sdim * This function will return the @a bucket to its allcoator.
86353944Sdim */
87353944Sdimvoid serf_default_destroy(
88353944Sdim    serf_bucket_t *bucket);
89353944Sdim
90353944Sdim
91353944Sdim/**
92353944Sdim * Default implementation of the @see destroy functionality.
93353944Sdim *
94353944Sdim * This function will return the @a bucket, and the data member to its
95353944Sdim * allocator.
96353944Sdim */
97353944Sdimvoid serf_default_destroy_and_data(
98353944Sdim    serf_bucket_t *bucket);
99353944Sdim
100353944Sdim
101353944Sdim/**
102353944Sdim * Allocate @a size bytes of memory using @a allocator.
103353944Sdim *
104353944Sdim * Returns NULL of the requested memory size could not be allocated.
105353944Sdim */
106353944Sdimvoid *serf_bucket_mem_alloc(
107353944Sdim    serf_bucket_alloc_t *allocator,
108353944Sdim    apr_size_t size);
109353944Sdim
110353944Sdim/**
111353944Sdim * Allocate @a size bytes of memory using @a allocator and set all of the
112353944Sdim * memory to 0.
113353944Sdim *
114353944Sdim * Returns NULL of the requested memory size could not be allocated.
115353944Sdim */
116353944Sdimvoid *serf_bucket_mem_calloc(
117353944Sdim    serf_bucket_alloc_t *allocator,
118353944Sdim    apr_size_t size);
119353944Sdim
120353944Sdim/**
121353944Sdim * Free the memory at @a block, returning it to @a allocator.
122353944Sdim */
123353944Sdimvoid serf_bucket_mem_free(
124353944Sdim    serf_bucket_alloc_t *allocator,
125353944Sdim    void *block);
126353944Sdim
127353944Sdim
128353944Sdim/**
129353944Sdim * Analogous to apr_pstrmemdup, using a bucket allocator instead.
130353944Sdim */
131353944Sdimchar *serf_bstrmemdup(
132353944Sdim    serf_bucket_alloc_t *allocator,
133353944Sdim    const char *str,
134353944Sdim    apr_size_t size);
135353944Sdim
136353944Sdim/**
137353944Sdim * Analogous to apr_pmemdup, using a bucket allocator instead.
138353944Sdim */
139353944Sdimvoid * serf_bmemdup(
140353944Sdim    serf_bucket_alloc_t *allocator,
141353944Sdim    const void *mem,
142353944Sdim    apr_size_t size);
143353944Sdim
144353944Sdim/**
145353944Sdim * Analogous to apr_pstrdup, using a bucket allocator instead.
146353944Sdim */
147353944Sdimchar * serf_bstrdup(
148353944Sdim    serf_bucket_alloc_t *allocator,
149353944Sdim    const char *str);
150353944Sdim
151353944Sdim/**
152353944Sdim * Analogous to apr_pstrcatv, using a bucket allocator instead.
153353944Sdim */
154353944Sdimchar * serf_bstrcatv(
155353944Sdim    serf_bucket_alloc_t *allocator,
156353944Sdim    struct iovec *vec,
157353944Sdim    int vecs,
158353944Sdim    apr_size_t *bytes_written);
159353944Sdim
160353944Sdim/**
161353944Sdim * Read data up to a newline.
162353944Sdim *
163353944Sdim * @a acceptable contains the allowed forms of a newline, and @a found
164353944Sdim * will return the particular newline type that was found. If a newline
165353944Sdim * is not found, then SERF_NEWLINE_NONE will be placed in @a found.
166353944Sdim *
167353944Sdim * @a data should contain a pointer to the data to be scanned. @a len
168353944Sdim * should specify the length of that data buffer. On exit, @a data will
169353944Sdim * be advanced past the newline, and @a len will specify the remaining
170353944Sdim * amount of data in the buffer.
171353944Sdim *
172353944Sdim * Given this pattern of behavior, the caller should store the initial
173353944Sdim * value of @a data as the line start. The difference between the
174353944Sdim * returned value of @a data and the saved start is the length of the
175353944Sdim * line.
176353944Sdim *
177353944Sdim * Note that the newline character(s) will remain within the buffer.
178353944Sdim * This function scans at a byte level for the newline characters. Thus,
179353944Sdim * the data buffer may contain NUL characters. As a corollary, this
180353944Sdim * function only works on 8-bit character encodings.
181353944Sdim *
182353944Sdim * If the data is fully consumed (@a len gets set to zero) and a CR
183353944Sdim * character is found at the end and the CRLF sequence is allowed, then
184353944Sdim * this function may store SERF_NEWLINE_CRLF_SPLIT into @a found. The
185353944Sdim * caller should take particular consideration for the CRLF sequence
186353944Sdim * that may be split across data buffer boundaries.
187353944Sdim */
188353944Sdimvoid serf_util_readline(
189353944Sdim    const char **data,
190353944Sdim    apr_size_t *len,
191353944Sdim    int acceptable,
192353944Sdim    int *found);
193353944Sdim
194353944Sdim
195353944Sdim/** The buffer size used within @see serf_databuf_t. */
196353944Sdim#define SERF_DATABUF_BUFSIZE 8000
197353944Sdim
198353944Sdim/** Callback function which is used to refill the data buffer.
199353944Sdim *
200353944Sdim * The function takes @a baton, which is the @see read_baton value
201353944Sdim * from the serf_databuf_t structure. Data should be placed into
202353944Sdim * a buffer specified by @a buf, which is @a bufsize bytes long.
203353944Sdim * The amount of data read should be returned in @a len.
204353944Sdim *
205353944Sdim * APR_EOF should be returned if no more data is available. APR_EAGAIN
206353944Sdim * should be returned, rather than blocking. In both cases, @a buf
207353944Sdim * should be filled in and @a len set, as appropriate.
208353944Sdim */
209353944Sdimtypedef apr_status_t (*serf_databuf_reader_t)(
210353944Sdim    void *baton,
211353944Sdim    apr_size_t bufsize,
212353944Sdim    char *buf,
213353944Sdim    apr_size_t *len);
214353944Sdim
215353944Sdim/**
216353944Sdim * This structure is used as an intermediate data buffer for some "external"
217353944Sdim * source of data. It works as a scratch pad area for incoming data to be
218353944Sdim * stored, and then returned as a ptr/len pair by the bucket read functions.
219353944Sdim *
220353944Sdim * This structure should be initialized by calling @see serf_databuf_init.
221353944Sdim * Users should not bother to zero the structure beforehand.
222353944Sdim */
223353944Sdimtypedef struct {
224353944Sdim    /** The current data position within the buffer. */
225353944Sdim    const char *current;
226353944Sdim
227353944Sdim    /** Amount of data remaining in the buffer. */
228353944Sdim    apr_size_t remaining;
229353944Sdim
230353944Sdim    /** Callback function. */
231353944Sdim    serf_databuf_reader_t read;
232353944Sdim
233353944Sdim    /** A baton to hold context-specific data. */
234353944Sdim    void *read_baton;
235353944Sdim
236353944Sdim    /** Records the status from the last @see read operation. */
237353944Sdim    apr_status_t status;
238353944Sdim
239353944Sdim    /** Holds the data until it can be returned. */
240353944Sdim    char buf[SERF_DATABUF_BUFSIZE];
241353944Sdim
242353944Sdim} serf_databuf_t;
243353944Sdim
244353944Sdim/**
245353944Sdim * Initialize the @see serf_databuf_t structure specified by @a databuf.
246353944Sdim */
247353944Sdimvoid serf_databuf_init(
248353944Sdim    serf_databuf_t *databuf);
249357095Sdim
250353944Sdim/**
251353944Sdim * Implement a bucket-style read function from the @see serf_databuf_t
252353944Sdim * structure given by @a databuf.
253353944Sdim *
254353944Sdim * The @a requested, @a data, and @a len fields are interpreted and used
255353944Sdim * as in the read function of @see serf_bucket_t.
256353944Sdim */
257353944Sdimapr_status_t serf_databuf_read(
258353944Sdim    serf_databuf_t *databuf,
259353944Sdim    apr_size_t requested,
260353944Sdim    const char **data,
261353944Sdim    apr_size_t *len);
262353944Sdim
263353944Sdim/**
264353944Sdim * Implement a bucket-style readline function from the @see serf_databuf_t
265353944Sdim * structure given by @a databuf.
266353944Sdim *
267353944Sdim * The @a acceptable, @a found, @a data, and @a len fields are interpreted
268353944Sdim * and used as in the read function of @see serf_bucket_t.
269353944Sdim */
270353944Sdimapr_status_t serf_databuf_readline(
271353944Sdim    serf_databuf_t *databuf,
272353944Sdim    int acceptable,
273353944Sdim    int *found,
274353944Sdim    const char **data,
275353944Sdim    apr_size_t *len);
276353944Sdim
277353944Sdim/**
278353944Sdim * Implement a bucket-style peek function from the @see serf_databuf_t
279353944Sdim * structure given by @a databuf.
280353944Sdim *
281353944Sdim * The @a data, and @a len fields are interpreted and used as in the
282353944Sdim * peek function of @see serf_bucket_t.
283353944Sdim */
284357095Sdimapr_status_t serf_databuf_peek(
285357095Sdim    serf_databuf_t *databuf,
286357095Sdim    const char **data,
287357095Sdim    apr_size_t *len);
288353944Sdim
289353944Sdim
290353944Sdim#ifdef __cplusplus
291353944Sdim}
292353944Sdim#endif
293353944Sdim
294353944Sdim#endif	/* !SERF_BUCKET_UTIL_H */
295353944Sdim