c8b001924d
Approved by: re (rgrimes)
300 lines
8.6 KiB
C
300 lines
8.6 KiB
C
/* ====================================================================
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
* ====================================================================
|
|
*/
|
|
|
|
#ifndef SERF_BUCKET_UTIL_H
|
|
#define SERF_BUCKET_UTIL_H
|
|
|
|
/**
|
|
* @file serf_bucket_util.h
|
|
* @brief This header defines a set of functions and other utilities
|
|
* for implementing buckets. It is not needed by users of the bucket
|
|
* system.
|
|
*/
|
|
|
|
#include "serf.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
/**
|
|
* Basic bucket creation function.
|
|
*
|
|
* This function will create a bucket of @a type, allocating the necessary
|
|
* memory from @a allocator. The @a data bucket-private information will
|
|
* be stored into the bucket.
|
|
*/
|
|
serf_bucket_t *serf_bucket_create(
|
|
const serf_bucket_type_t *type,
|
|
serf_bucket_alloc_t *allocator,
|
|
void *data);
|
|
|
|
/**
|
|
* Default implementation of the @see read_iovec functionality.
|
|
*
|
|
* This function will use the @see read function to get a block of memory,
|
|
* then return it in the iovec.
|
|
*/
|
|
apr_status_t serf_default_read_iovec(
|
|
serf_bucket_t *bucket,
|
|
apr_size_t requested,
|
|
int vecs_size,
|
|
struct iovec *vecs,
|
|
int *vecs_used);
|
|
|
|
/**
|
|
* Default implementation of the @see read_for_sendfile functionality.
|
|
*
|
|
* This function will use the @see read function to get a block of memory,
|
|
* then return it as a header. No file will be returned.
|
|
*/
|
|
apr_status_t serf_default_read_for_sendfile(
|
|
serf_bucket_t *bucket,
|
|
apr_size_t requested,
|
|
apr_hdtr_t *hdtr,
|
|
apr_file_t **file,
|
|
apr_off_t *offset,
|
|
apr_size_t *len);
|
|
|
|
/**
|
|
* Default implementation of the @see read_bucket functionality.
|
|
*
|
|
* This function will always return NULL, indicating that the @a type
|
|
* of bucket cannot be found within @a bucket.
|
|
*/
|
|
serf_bucket_t *serf_default_read_bucket(
|
|
serf_bucket_t *bucket,
|
|
const serf_bucket_type_t *type);
|
|
|
|
/**
|
|
* Default implementation of the @see destroy functionality.
|
|
*
|
|
* This function will return the @a bucket to its allcoator.
|
|
*/
|
|
void serf_default_destroy(
|
|
serf_bucket_t *bucket);
|
|
|
|
|
|
/**
|
|
* Default implementation of the @see destroy functionality.
|
|
*
|
|
* This function will return the @a bucket, and the data member to its
|
|
* allocator.
|
|
*/
|
|
void serf_default_destroy_and_data(
|
|
serf_bucket_t *bucket);
|
|
|
|
|
|
/**
|
|
* Allocate @a size bytes of memory using @a allocator.
|
|
*
|
|
* Returns NULL of the requested memory size could not be allocated.
|
|
*/
|
|
void *serf_bucket_mem_alloc(
|
|
serf_bucket_alloc_t *allocator,
|
|
apr_size_t size);
|
|
|
|
/**
|
|
* Allocate @a size bytes of memory using @a allocator and set all of the
|
|
* memory to 0.
|
|
*
|
|
* Returns NULL of the requested memory size could not be allocated.
|
|
*/
|
|
void *serf_bucket_mem_calloc(
|
|
serf_bucket_alloc_t *allocator,
|
|
apr_size_t size);
|
|
|
|
/**
|
|
* Free the memory at @a block, returning it to @a allocator.
|
|
*/
|
|
void serf_bucket_mem_free(
|
|
serf_bucket_alloc_t *allocator,
|
|
void *block);
|
|
|
|
|
|
/**
|
|
* Analogous to apr_pstrmemdup, using a bucket allocator instead.
|
|
*/
|
|
char *serf_bstrmemdup(
|
|
serf_bucket_alloc_t *allocator,
|
|
const char *str,
|
|
apr_size_t size);
|
|
|
|
/**
|
|
* Analogous to apr_pmemdup, using a bucket allocator instead.
|
|
*/
|
|
void * serf_bmemdup(
|
|
serf_bucket_alloc_t *allocator,
|
|
const void *mem,
|
|
apr_size_t size);
|
|
|
|
/**
|
|
* Analogous to apr_pstrdup, using a bucket allocator instead.
|
|
*/
|
|
char * serf_bstrdup(
|
|
serf_bucket_alloc_t *allocator,
|
|
const char *str);
|
|
|
|
/**
|
|
* Analogous to apr_pstrcatv, using a bucket allocator instead.
|
|
*/
|
|
char * serf_bstrcatv(
|
|
serf_bucket_alloc_t *allocator,
|
|
struct iovec *vec,
|
|
int vecs,
|
|
apr_size_t *bytes_written);
|
|
|
|
/**
|
|
* Read data up to a newline.
|
|
*
|
|
* @a acceptable contains the allowed forms of a newline, and @a found
|
|
* will return the particular newline type that was found. If a newline
|
|
* is not found, then SERF_NEWLINE_NONE will be placed in @a found.
|
|
*
|
|
* @a data should contain a pointer to the data to be scanned. @a len
|
|
* should specify the length of that data buffer. On exit, @a data will
|
|
* be advanced past the newline, and @a len will specify the remaining
|
|
* amount of data in the buffer.
|
|
*
|
|
* Given this pattern of behavior, the caller should store the initial
|
|
* value of @a data as the line start. The difference between the
|
|
* returned value of @a data and the saved start is the length of the
|
|
* line.
|
|
*
|
|
* Note that the newline character(s) will remain within the buffer.
|
|
* This function scans at a byte level for the newline characters. Thus,
|
|
* the data buffer may contain NUL characters. As a corollary, this
|
|
* function only works on 8-bit character encodings.
|
|
*
|
|
* If the data is fully consumed (@a len gets set to zero) and a CR
|
|
* character is found at the end and the CRLF sequence is allowed, then
|
|
* this function may store SERF_NEWLINE_CRLF_SPLIT into @a found. The
|
|
* caller should take particular consideration for the CRLF sequence
|
|
* that may be split across data buffer boundaries.
|
|
*/
|
|
void serf_util_readline(
|
|
const char **data,
|
|
apr_size_t *len,
|
|
int acceptable,
|
|
int *found);
|
|
|
|
|
|
/** The buffer size used within @see serf_databuf_t. */
|
|
#define SERF_DATABUF_BUFSIZE 8000
|
|
|
|
/** Callback function which is used to refill the data buffer.
|
|
*
|
|
* The function takes @a baton, which is the @see read_baton value
|
|
* from the serf_databuf_t structure. Data should be placed into
|
|
* a buffer specified by @a buf, which is @a bufsize bytes long.
|
|
* The amount of data read should be returned in @a len.
|
|
*
|
|
* APR_EOF should be returned if no more data is available. APR_EAGAIN
|
|
* should be returned, rather than blocking. In both cases, @a buf
|
|
* should be filled in and @a len set, as appropriate.
|
|
*/
|
|
typedef apr_status_t (*serf_databuf_reader_t)(
|
|
void *baton,
|
|
apr_size_t bufsize,
|
|
char *buf,
|
|
apr_size_t *len);
|
|
|
|
/**
|
|
* This structure is used as an intermediate data buffer for some "external"
|
|
* source of data. It works as a scratch pad area for incoming data to be
|
|
* stored, and then returned as a ptr/len pair by the bucket read functions.
|
|
*
|
|
* This structure should be initialized by calling @see serf_databuf_init.
|
|
* Users should not bother to zero the structure beforehand.
|
|
*/
|
|
typedef struct {
|
|
/** The current data position within the buffer. */
|
|
const char *current;
|
|
|
|
/** Amount of data remaining in the buffer. */
|
|
apr_size_t remaining;
|
|
|
|
/** Callback function. */
|
|
serf_databuf_reader_t read;
|
|
|
|
/** A baton to hold context-specific data. */
|
|
void *read_baton;
|
|
|
|
/** Records the status from the last @see read operation. */
|
|
apr_status_t status;
|
|
|
|
/** Holds the data until it can be returned. */
|
|
char buf[SERF_DATABUF_BUFSIZE];
|
|
|
|
} serf_databuf_t;
|
|
|
|
/**
|
|
* Initialize the @see serf_databuf_t structure specified by @a databuf.
|
|
*/
|
|
void serf_databuf_init(
|
|
serf_databuf_t *databuf);
|
|
|
|
/**
|
|
* Implement a bucket-style read function from the @see serf_databuf_t
|
|
* structure given by @a databuf.
|
|
*
|
|
* The @a requested, @a data, and @a len fields are interpreted and used
|
|
* as in the read function of @see serf_bucket_t.
|
|
*/
|
|
apr_status_t serf_databuf_read(
|
|
serf_databuf_t *databuf,
|
|
apr_size_t requested,
|
|
const char **data,
|
|
apr_size_t *len);
|
|
|
|
/**
|
|
* Implement a bucket-style readline function from the @see serf_databuf_t
|
|
* structure given by @a databuf.
|
|
*
|
|
* The @a acceptable, @a found, @a data, and @a len fields are interpreted
|
|
* and used as in the read function of @see serf_bucket_t.
|
|
*/
|
|
apr_status_t serf_databuf_readline(
|
|
serf_databuf_t *databuf,
|
|
int acceptable,
|
|
int *found,
|
|
const char **data,
|
|
apr_size_t *len);
|
|
|
|
/**
|
|
* Implement a bucket-style peek function from the @see serf_databuf_t
|
|
* structure given by @a databuf.
|
|
*
|
|
* The @a data, and @a len fields are interpreted and used as in the
|
|
* peek function of @see serf_bucket_t.
|
|
*/
|
|
apr_status_t serf_databuf_peek(
|
|
serf_databuf_t *databuf,
|
|
const char **data,
|
|
apr_size_t *len);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* !SERF_BUCKET_UTIL_H */
|