Blame serf_bucket_util.h

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