1362181Sdim/* ====================================================================
2362181Sdim *    Licensed to the Apache Software Foundation (ASF) under one
3362181Sdim *    or more contributor license agreements.  See the NOTICE file
4362181Sdim *    distributed with this work for additional information
5362181Sdim *    regarding copyright ownership.  The ASF licenses this file
6362181Sdim *    to you under the Apache License, Version 2.0 (the
7362181Sdim *    "License"); you may not use this file except in compliance
8362181Sdim *    with the License.  You may obtain a copy of the License at
9251877Speter *
10362181Sdim *      http://www.apache.org/licenses/LICENSE-2.0
11251877Speter *
12362181Sdim *    Unless required by applicable law or agreed to in writing,
13362181Sdim *    software distributed under the License is distributed on an
14362181Sdim *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15362181Sdim *    KIND, either express or implied.  See the License for the
16362181Sdim *    specific language governing permissions and limitations
17362181Sdim *    under the License.
18362181Sdim * ====================================================================
19251877Speter */
20251877Speter
21251877Speter#ifndef SERF_BUCKET_UTIL_H
22251877Speter#define SERF_BUCKET_UTIL_H
23251877Speter
24251877Speter/**
25251877Speter * @file serf_bucket_util.h
26251877Speter * @brief This header defines a set of functions and other utilities
27251877Speter * for implementing buckets. It is not needed by users of the bucket
28251877Speter * system.
29251877Speter */
30251877Speter
31251877Speter#include "serf.h"
32251877Speter
33251877Speter#ifdef __cplusplus
34251877Speterextern "C" {
35251877Speter#endif
36251877Speter
37251877Speter
38251877Speter/**
39251877Speter * Basic bucket creation function.
40251877Speter *
41251877Speter * This function will create a bucket of @a type, allocating the necessary
42251877Speter * memory from @a allocator. The @a data bucket-private information will
43251877Speter * be stored into the bucket.
44251877Speter */
45251877Speterserf_bucket_t *serf_bucket_create(
46251877Speter    const serf_bucket_type_t *type,
47251877Speter    serf_bucket_alloc_t *allocator,
48251877Speter    void *data);
49251877Speter
50251877Speter/**
51251877Speter * Default implementation of the @see read_iovec functionality.
52251877Speter *
53251877Speter * This function will use the @see read function to get a block of memory,
54251877Speter * then return it in the iovec.
55251877Speter */
56251877Speterapr_status_t serf_default_read_iovec(
57251877Speter    serf_bucket_t *bucket,
58251877Speter    apr_size_t requested,
59251877Speter    int vecs_size,
60251877Speter    struct iovec *vecs,
61251877Speter    int *vecs_used);
62251877Speter
63251877Speter/**
64251877Speter * Default implementation of the @see read_for_sendfile functionality.
65251877Speter *
66251877Speter * This function will use the @see read function to get a block of memory,
67251877Speter * then return it as a header. No file will be returned.
68251877Speter */
69251877Speterapr_status_t serf_default_read_for_sendfile(
70251877Speter    serf_bucket_t *bucket,
71251877Speter    apr_size_t requested,
72251877Speter    apr_hdtr_t *hdtr,
73251877Speter    apr_file_t **file,
74251877Speter    apr_off_t *offset,
75251877Speter    apr_size_t *len);
76251877Speter
77251877Speter/**
78251877Speter * Default implementation of the @see read_bucket functionality.
79251877Speter *
80251877Speter * This function will always return NULL, indicating that the @a type
81251877Speter * of bucket cannot be found within @a bucket.
82251877Speter */
83251877Speterserf_bucket_t *serf_default_read_bucket(
84251877Speter    serf_bucket_t *bucket,
85251877Speter    const serf_bucket_type_t *type);
86251877Speter
87251877Speter/**
88251877Speter * Default implementation of the @see destroy functionality.
89251877Speter *
90251877Speter * This function will return the @a bucket to its allcoator.
91251877Speter */
92251877Spetervoid serf_default_destroy(
93251877Speter    serf_bucket_t *bucket);
94251877Speter
95251877Speter
96251877Speter/**
97251877Speter * Default implementation of the @see destroy functionality.
98251877Speter *
99251877Speter * This function will return the @a bucket, and the data member to its
100251877Speter * allocator.
101251877Speter */
102251877Spetervoid serf_default_destroy_and_data(
103251877Speter    serf_bucket_t *bucket);
104251877Speter
105251877Speter
106251877Speter/**
107251877Speter * Allocate @a size bytes of memory using @a allocator.
108251877Speter *
109251877Speter * Returns NULL of the requested memory size could not be allocated.
110251877Speter */
111251877Spetervoid *serf_bucket_mem_alloc(
112251877Speter    serf_bucket_alloc_t *allocator,
113251877Speter    apr_size_t size);
114251877Speter
115251877Speter/**
116251877Speter * Allocate @a size bytes of memory using @a allocator and set all of the
117251877Speter * memory to 0.
118251877Speter *
119251877Speter * Returns NULL of the requested memory size could not be allocated.
120251877Speter */
121251877Spetervoid *serf_bucket_mem_calloc(
122251877Speter    serf_bucket_alloc_t *allocator,
123251877Speter    apr_size_t size);
124251877Speter
125251877Speter/**
126251877Speter * Free the memory at @a block, returning it to @a allocator.
127251877Speter */
128251877Spetervoid serf_bucket_mem_free(
129251877Speter    serf_bucket_alloc_t *allocator,
130251877Speter    void *block);
131251877Speter
132251877Speter
133251877Speter/**
134251877Speter * Analogous to apr_pstrmemdup, using a bucket allocator instead.
135251877Speter */
136251877Speterchar *serf_bstrmemdup(
137251877Speter    serf_bucket_alloc_t *allocator,
138251877Speter    const char *str,
139251877Speter    apr_size_t size);
140251877Speter
141251877Speter/**
142251877Speter * Analogous to apr_pmemdup, using a bucket allocator instead.
143251877Speter */
144251877Spetervoid * serf_bmemdup(
145251877Speter    serf_bucket_alloc_t *allocator,
146251877Speter    const void *mem,
147251877Speter    apr_size_t size);
148251877Speter
149251877Speter/**
150251877Speter * Analogous to apr_pstrdup, using a bucket allocator instead.
151251877Speter */
152251877Speterchar * serf_bstrdup(
153251877Speter    serf_bucket_alloc_t *allocator,
154251877Speter    const char *str);
155251877Speter
156253895Speter/**
157253895Speter * Analogous to apr_pstrcatv, using a bucket allocator instead.
158253895Speter */
159253895Speterchar * serf_bstrcatv(
160253895Speter    serf_bucket_alloc_t *allocator,
161253895Speter    struct iovec *vec,
162253895Speter    int vecs,
163253895Speter    apr_size_t *bytes_written);
164251877Speter
165251877Speter/**
166251877Speter * Read data up to a newline.
167251877Speter *
168251877Speter * @a acceptable contains the allowed forms of a newline, and @a found
169251877Speter * will return the particular newline type that was found. If a newline
170251877Speter * is not found, then SERF_NEWLINE_NONE will be placed in @a found.
171251877Speter *
172251877Speter * @a data should contain a pointer to the data to be scanned. @a len
173251877Speter * should specify the length of that data buffer. On exit, @a data will
174251877Speter * be advanced past the newline, and @a len will specify the remaining
175251877Speter * amount of data in the buffer.
176251877Speter *
177251877Speter * Given this pattern of behavior, the caller should store the initial
178251877Speter * value of @a data as the line start. The difference between the
179251877Speter * returned value of @a data and the saved start is the length of the
180251877Speter * line.
181251877Speter *
182251877Speter * Note that the newline character(s) will remain within the buffer.
183251877Speter * This function scans at a byte level for the newline characters. Thus,
184251877Speter * the data buffer may contain NUL characters. As a corollary, this
185251877Speter * function only works on 8-bit character encodings.
186251877Speter *
187251877Speter * If the data is fully consumed (@a len gets set to zero) and a CR
188251877Speter * character is found at the end and the CRLF sequence is allowed, then
189251877Speter * this function may store SERF_NEWLINE_CRLF_SPLIT into @a found. The
190251877Speter * caller should take particular consideration for the CRLF sequence
191251877Speter * that may be split across data buffer boundaries.
192251877Speter */
193251877Spetervoid serf_util_readline(
194251877Speter    const char **data,
195251877Speter    apr_size_t *len,
196251877Speter    int acceptable,
197251877Speter    int *found);
198251877Speter
199251877Speter
200251877Speter/** The buffer size used within @see serf_databuf_t. */
201251877Speter#define SERF_DATABUF_BUFSIZE 8000
202251877Speter
203251877Speter/** Callback function which is used to refill the data buffer.
204251877Speter *
205251877Speter * The function takes @a baton, which is the @see read_baton value
206251877Speter * from the serf_databuf_t structure. Data should be placed into
207251877Speter * a buffer specified by @a buf, which is @a bufsize bytes long.
208251877Speter * The amount of data read should be returned in @a len.
209251877Speter *
210251877Speter * APR_EOF should be returned if no more data is available. APR_EAGAIN
211251877Speter * should be returned, rather than blocking. In both cases, @a buf
212251877Speter * should be filled in and @a len set, as appropriate.
213251877Speter */
214251877Spetertypedef apr_status_t (*serf_databuf_reader_t)(
215251877Speter    void *baton,
216251877Speter    apr_size_t bufsize,
217251877Speter    char *buf,
218251877Speter    apr_size_t *len);
219251877Speter
220251877Speter/**
221251877Speter * This structure is used as an intermediate data buffer for some "external"
222251877Speter * source of data. It works as a scratch pad area for incoming data to be
223251877Speter * stored, and then returned as a ptr/len pair by the bucket read functions.
224251877Speter *
225251877Speter * This structure should be initialized by calling @see serf_databuf_init.
226251877Speter * Users should not bother to zero the structure beforehand.
227251877Speter */
228251877Spetertypedef struct {
229251877Speter    /** The current data position within the buffer. */
230251877Speter    const char *current;
231251877Speter
232251877Speter    /** Amount of data remaining in the buffer. */
233251877Speter    apr_size_t remaining;
234251877Speter
235251877Speter    /** Callback function. */
236251877Speter    serf_databuf_reader_t read;
237251877Speter
238251877Speter    /** A baton to hold context-specific data. */
239251877Speter    void *read_baton;
240251877Speter
241251877Speter    /** Records the status from the last @see read operation. */
242251877Speter    apr_status_t status;
243251877Speter
244251877Speter    /** Holds the data until it can be returned. */
245251877Speter    char buf[SERF_DATABUF_BUFSIZE];
246251877Speter
247251877Speter} serf_databuf_t;
248251877Speter
249251877Speter/**
250251877Speter * Initialize the @see serf_databuf_t structure specified by @a databuf.
251251877Speter */
252251877Spetervoid serf_databuf_init(
253251877Speter    serf_databuf_t *databuf);
254251877Speter
255251877Speter/**
256251877Speter * Implement a bucket-style read function from the @see serf_databuf_t
257251877Speter * structure given by @a databuf.
258251877Speter *
259251877Speter * The @a requested, @a data, and @a len fields are interpreted and used
260251877Speter * as in the read function of @see serf_bucket_t.
261251877Speter */
262251877Speterapr_status_t serf_databuf_read(
263251877Speter    serf_databuf_t *databuf,
264251877Speter    apr_size_t requested,
265251877Speter    const char **data,
266251877Speter    apr_size_t *len);
267251877Speter
268251877Speter/**
269251877Speter * Implement a bucket-style readline function from the @see serf_databuf_t
270251877Speter * structure given by @a databuf.
271251877Speter *
272251877Speter * The @a acceptable, @a found, @a data, and @a len fields are interpreted
273251877Speter * and used as in the read function of @see serf_bucket_t.
274251877Speter */
275251877Speterapr_status_t serf_databuf_readline(
276251877Speter    serf_databuf_t *databuf,
277251877Speter    int acceptable,
278251877Speter    int *found,
279251877Speter    const char **data,
280251877Speter    apr_size_t *len);
281251877Speter
282251877Speter/**
283251877Speter * Implement a bucket-style peek function from the @see serf_databuf_t
284251877Speter * structure given by @a databuf.
285251877Speter *
286251877Speter * The @a data, and @a len fields are interpreted and used as in the
287251877Speter * peek function of @see serf_bucket_t.
288251877Speter */
289251877Speterapr_status_t serf_databuf_peek(
290251877Speter    serf_databuf_t *databuf,
291251877Speter    const char **data,
292251877Speter    apr_size_t *len);
293251877Speter
294251877Speter
295251877Speter#ifdef __cplusplus
296251877Speter}
297251877Speter#endif
298251877Speter
299251877Speter#endif	/* !SERF_BUCKET_UTIL_H */
300