/src/httpd/srclib/apr/buckets/apr_buckets_simple.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Licensed to the Apache Software Foundation (ASF) under one or more |
2 | | * contributor license agreements. See the NOTICE file distributed with |
3 | | * this work for additional information regarding copyright ownership. |
4 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
5 | | * (the "License"); you may not use this file except in compliance with |
6 | | * the License. You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include "apr_buckets.h" |
18 | | |
19 | | APR_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_copy(apr_bucket *a, |
20 | | apr_bucket **b) |
21 | 9.22k | { |
22 | 9.22k | *b = apr_bucket_alloc(sizeof(**b), a->list); /* XXX: check for failure? */ |
23 | 9.22k | **b = *a; |
24 | | |
25 | 9.22k | return APR_SUCCESS; |
26 | 9.22k | } |
27 | | |
28 | | APR_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *a, |
29 | | apr_size_t point) |
30 | 9.22k | { |
31 | 9.22k | apr_bucket *b; |
32 | | |
33 | 9.22k | if (point > a->length) { |
34 | 0 | return APR_EINVAL; |
35 | 0 | } |
36 | | |
37 | 9.22k | apr_bucket_simple_copy(a, &b); |
38 | | |
39 | 9.22k | a->length = point; |
40 | 9.22k | b->length -= point; |
41 | 9.22k | b->start += point; |
42 | | |
43 | 9.22k | APR_BUCKET_INSERT_AFTER(a, b); |
44 | | |
45 | 9.22k | return APR_SUCCESS; |
46 | 9.22k | } |
47 | | |
48 | | static apr_status_t simple_bucket_read(apr_bucket *b, const char **str, |
49 | | apr_size_t *len, apr_read_type_e block) |
50 | 9 | { |
51 | 9 | *str = (char *)b->data + b->start; |
52 | 9 | *len = b->length; |
53 | 9 | return APR_SUCCESS; |
54 | 9 | } |
55 | | |
56 | | APR_DECLARE(apr_bucket *) apr_bucket_immortal_make(apr_bucket *b, |
57 | | const char *buf, |
58 | | apr_size_t length) |
59 | 9 | { |
60 | 9 | b->data = (char *)buf; |
61 | 9 | b->length = length; |
62 | 9 | b->start = 0; |
63 | 9 | b->type = &apr_bucket_type_immortal; |
64 | | |
65 | 9 | return b; |
66 | 9 | } |
67 | | |
68 | | APR_DECLARE(apr_bucket *) apr_bucket_immortal_create(const char *buf, |
69 | | apr_size_t length, |
70 | | apr_bucket_alloc_t *list) |
71 | 9 | { |
72 | 9 | apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); |
73 | | |
74 | 9 | APR_BUCKET_INIT(b); |
75 | 9 | b->free = apr_bucket_free; |
76 | 9 | b->list = list; |
77 | 9 | return apr_bucket_immortal_make(b, buf, length); |
78 | 9 | } |
79 | | |
80 | | /* |
81 | | * XXX: This function could do with some tweaking to reduce memory |
82 | | * usage in various cases, e.g. share buffers in the heap between all |
83 | | * the buckets that are set aside, or even spool set-aside data to |
84 | | * disk if it gets too voluminous (but if it does then that's probably |
85 | | * a bug elsewhere). There should probably be a apr_brigade_setaside() |
86 | | * function that co-ordinates the action of all the bucket setaside |
87 | | * functions to improve memory efficiency. |
88 | | */ |
89 | | static apr_status_t transient_bucket_setaside(apr_bucket *b, apr_pool_t *pool) |
90 | 0 | { |
91 | 0 | b = apr_bucket_heap_make(b, (char *)b->data + b->start, b->length, NULL); |
92 | 0 | if (b == NULL) { |
93 | 0 | return APR_ENOMEM; |
94 | 0 | } |
95 | 0 | return APR_SUCCESS; |
96 | 0 | } |
97 | | |
98 | | APR_DECLARE(apr_bucket *) apr_bucket_transient_make(apr_bucket *b, |
99 | | const char *buf, |
100 | | apr_size_t length) |
101 | 0 | { |
102 | 0 | b->data = (char *)buf; |
103 | 0 | b->length = length; |
104 | 0 | b->start = 0; |
105 | 0 | b->type = &apr_bucket_type_transient; |
106 | 0 | return b; |
107 | 0 | } |
108 | | |
109 | | APR_DECLARE(apr_bucket *) apr_bucket_transient_create(const char *buf, |
110 | | apr_size_t length, |
111 | | apr_bucket_alloc_t *list) |
112 | 0 | { |
113 | 0 | apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); |
114 | |
|
115 | 0 | APR_BUCKET_INIT(b); |
116 | 0 | b->free = apr_bucket_free; |
117 | 0 | b->list = list; |
118 | 0 | return apr_bucket_transient_make(b, buf, length); |
119 | 0 | } |
120 | | |
121 | | const apr_bucket_type_t apr_bucket_type_immortal = { |
122 | | "IMMORTAL", 5, APR_BUCKET_DATA, |
123 | | apr_bucket_destroy_noop, |
124 | | simple_bucket_read, |
125 | | apr_bucket_setaside_noop, |
126 | | apr_bucket_simple_split, |
127 | | apr_bucket_simple_copy |
128 | | }; |
129 | | |
130 | | APR_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_transient = { |
131 | | "TRANSIENT", 5, APR_BUCKET_DATA, |
132 | | apr_bucket_destroy_noop, |
133 | | simple_bucket_read, |
134 | | transient_bucket_setaside, |
135 | | apr_bucket_simple_split, |
136 | | apr_bucket_simple_copy |
137 | | }; |