/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "apr_buckets.h"
#include <stdlib.h>

static apr_status_t pool_bucket_cleanup(void *data)
{
    apr_bucket_pool *p = data;

    /*
     * If the pool gets cleaned up, we have to copy the data out
     * of the pool and onto the heap.  But the apr_buckets out there
     * that point to this pool bucket need to be notified such that
     * they can morph themselves into a regular heap bucket the next
     * time they try to read.  To avoid having to manipulate
     * reference counts and b->data pointers, the apr_bucket_pool
     * actually _contains_ an apr_bucket_heap as its first element,
     * so the two share their apr_bucket_refcount member, and you
     * can typecast a pool bucket struct to make it look like a
     * regular old heap bucket struct.
     */
    p->heap.base = malloc(p->heap.alloc_len);
    memcpy(p->heap.base, p->base, p->heap.alloc_len);
    p->base = NULL;
    p->pool = NULL;

    return APR_SUCCESS;
}

static apr_status_t pool_read(apr_bucket *b, const char **str, 
			      apr_size_t *len, apr_read_type_e block)
{
    apr_bucket_pool *p = b->data;
    const char *base = p->base;

    if (p->pool == NULL) {
        /*
         * pool has been cleaned up... masquerade as a heap bucket from now
         * on. subsequent bucket operations will use the heap bucket code.
         */
        b->type = &apr_bucket_type_heap;
        base = p->heap.base;
    }
    *str = base + b->start;
    *len = b->length;
    return APR_SUCCESS;
}

static void pool_destroy(void *data)
{
    apr_bucket_pool *p = data;

    /* If the pool is cleaned up before the last reference goes
     * away, buckets that have performed at least one read will
     * have been turned into heap buckets, so heap_destroy() takes
     * over.  If the very last reference to be destroyed now
     * considers itself a heap bucket, we don't have to worry about
     * it anymore... free() in heap_destroy() thinks it's freeing
     * an apr_bucket_heap, when in reality it's freeing the whole
     * apr_bucket_pool for us.  We have to be a little careful, though,
     * because it's _possible_ the very last reference to be destroyed
     * has never been read since the pool was cleaned up, in which
     * case we have to avoid deregistering a pool cleanup that
     * has already taken place.
     */
    if (apr_bucket_shared_destroy(p)) {
        if (p->pool) {
            apr_pool_cleanup_kill(p->pool, p, pool_bucket_cleanup);
        }
        free(p);
    }
}

APU_DECLARE(apr_bucket *) apr_bucket_pool_make(apr_bucket *b,
                      const char *buf, apr_size_t length, apr_pool_t *pool)
{
    apr_bucket_pool *p;

    p = malloc(sizeof(*p));
    if (p == NULL) {
	return NULL;
    }

    /* XXX: we lose the const qualifier here which indicates
     * there's something screwy with the API...
     */
    /* XXX: why is this?  buf is const, p->base is const... what's
     * the problem?  --jcw */
    p->base = (char *) buf;
    p->pool = pool;

    b = apr_bucket_shared_make(b, p, 0, length);
    b->type = &apr_bucket_type_pool;

    /* pre-initialize heap bucket member */
    p->heap.alloc_len = length;
    p->heap.base      = NULL;

    apr_pool_cleanup_register(p->pool, p, pool_bucket_cleanup,
                              apr_pool_cleanup_null);
    return b;
}

APU_DECLARE(apr_bucket *) apr_bucket_pool_create(
		const char *buf, apr_size_t length, apr_pool_t *pool)
{
    apr_bucket_do_create(apr_bucket_pool_make(b, buf, length, pool));
}

APU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_pool = {
    "POOL", 5,
    pool_destroy,
    pool_read,
    apr_bucket_setaside_notimpl,
    apr_bucket_shared_split,
    apr_bucket_shared_copy
};
