1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2251876Speter * contributor license agreements.  See the NOTICE file distributed with
3251876Speter * this work for additional information regarding copyright ownership.
4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5251876Speter * (the "License"); you may not use this file except in compliance with
6251876Speter * the License.  You may obtain a copy of the License at
7251876Speter *
8251876Speter *     http://www.apache.org/licenses/LICENSE-2.0
9251876Speter *
10251876Speter * Unless required by applicable law or agreed to in writing, software
11251876Speter * distributed under the License is distributed on an "AS IS" BASIS,
12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13251876Speter * See the License for the specific language governing permissions and
14251876Speter * limitations under the License.
15251876Speter */
16251876Speter
17251876Speter#include "apr_buckets.h"
18251876Speter#define APR_WANT_MEMFUNC
19251876Speter#include "apr_want.h"
20251876Speter
21251876Speterstatic apr_status_t heap_bucket_read(apr_bucket *b, const char **str,
22251876Speter                                     apr_size_t *len, apr_read_type_e block)
23251876Speter{
24251876Speter    apr_bucket_heap *h = b->data;
25251876Speter
26251876Speter    *str = h->base + b->start;
27251876Speter    *len = b->length;
28251876Speter    return APR_SUCCESS;
29251876Speter}
30251876Speter
31251876Speterstatic void heap_bucket_destroy(void *data)
32251876Speter{
33251876Speter    apr_bucket_heap *h = data;
34251876Speter
35251876Speter    if (apr_bucket_shared_destroy(h)) {
36251876Speter        (*h->free_func)(h->base);
37251876Speter        apr_bucket_free(h);
38251876Speter    }
39251876Speter}
40251876Speter
41251876Speter/* Warning: if you change this function, be sure to
42251876Speter * change apr_bucket_pool_make() too! */
43251876SpeterAPU_DECLARE(apr_bucket *) apr_bucket_heap_make(apr_bucket *b, const char *buf,
44251876Speter                                               apr_size_t length,
45251876Speter                                               void (*free_func)(void *data))
46251876Speter{
47251876Speter    apr_bucket_heap *h;
48251876Speter
49251876Speter    h = apr_bucket_alloc(sizeof(*h), b->list);
50251876Speter
51251876Speter    if (!free_func) {
52251876Speter        h->alloc_len = length;
53251876Speter        h->base = apr_bucket_alloc(h->alloc_len, b->list);
54251876Speter        if (h->base == NULL) {
55251876Speter            apr_bucket_free(h);
56251876Speter            return NULL;
57251876Speter        }
58251876Speter        h->free_func = apr_bucket_free;
59251876Speter        memcpy(h->base, buf, length);
60251876Speter    }
61251876Speter    else {
62251876Speter        /* XXX: we lose the const qualifier here which indicates
63251876Speter         * there's something screwy with the API...
64251876Speter         */
65251876Speter        h->base = (char *) buf;
66251876Speter        h->alloc_len = length;
67251876Speter        h->free_func = free_func;
68251876Speter    }
69251876Speter
70251876Speter    b = apr_bucket_shared_make(b, h, 0, length);
71251876Speter    b->type = &apr_bucket_type_heap;
72251876Speter
73251876Speter    return b;
74251876Speter}
75251876Speter
76251876SpeterAPU_DECLARE(apr_bucket *) apr_bucket_heap_create(const char *buf,
77251876Speter                                                 apr_size_t length,
78251876Speter                                                 void (*free_func)(void *data),
79251876Speter                                                 apr_bucket_alloc_t *list)
80251876Speter{
81251876Speter    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
82251876Speter
83251876Speter    APR_BUCKET_INIT(b);
84251876Speter    b->free = apr_bucket_free;
85251876Speter    b->list = list;
86251876Speter    return apr_bucket_heap_make(b, buf, length, free_func);
87251876Speter}
88251876Speter
89251876SpeterAPU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_heap = {
90251876Speter    "HEAP", 5, APR_BUCKET_DATA,
91251876Speter    heap_bucket_destroy,
92251876Speter    heap_bucket_read,
93251876Speter    apr_bucket_setaside_noop,
94251876Speter    apr_bucket_shared_split,
95251876Speter    apr_bucket_shared_copy
96251876Speter};
97