1 /* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <apr_pools.h>
19 #include "serf_bucket_util.h"
27 serf_simple_freefunc_t freefunc;
33 static void free_copied_data(void *baton, const char *data)
35 serf_bucket_mem_free(baton, (char*)data);
38 serf_bucket_t *serf_bucket_simple_create(
41 serf_simple_freefunc_t freefunc,
43 serf_bucket_alloc_t *allocator)
45 simple_context_t *ctx;
47 ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
48 ctx->original = ctx->current = data;
50 ctx->freefunc = freefunc;
51 ctx->baton = freefunc_baton;
53 return serf_bucket_create(&serf_bucket_type_simple, allocator, ctx);
56 serf_bucket_t *serf_bucket_simple_copy_create(
57 const char *data, apr_size_t len,
58 serf_bucket_alloc_t *allocator)
60 simple_context_t *ctx;
62 ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
64 ctx->original = ctx->current = serf_bucket_mem_alloc(allocator, len);
65 memcpy((char*)ctx->original, data, len);
68 ctx->freefunc = free_copied_data;
69 ctx->baton = allocator;
71 return serf_bucket_create(&serf_bucket_type_simple, allocator, ctx);
74 serf_bucket_t *serf_bucket_simple_own_create(
75 const char *data, apr_size_t len,
76 serf_bucket_alloc_t *allocator)
78 simple_context_t *ctx;
80 ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
82 ctx->original = ctx->current = data;
85 ctx->freefunc = free_copied_data;
86 ctx->baton = allocator;
88 return serf_bucket_create(&serf_bucket_type_simple, allocator, ctx);
91 static apr_status_t serf_simple_read(serf_bucket_t *bucket,
93 const char **data, apr_size_t *len)
95 simple_context_t *ctx = bucket->data;
97 if (requested == SERF_READ_ALL_AVAIL || requested > ctx->remaining)
98 requested = ctx->remaining;
100 *data = ctx->current;
103 ctx->current += requested;
104 ctx->remaining -= requested;
106 return ctx->remaining ? APR_SUCCESS : APR_EOF;
109 static apr_status_t serf_simple_readline(serf_bucket_t *bucket,
110 int acceptable, int *found,
111 const char **data, apr_size_t *len)
113 simple_context_t *ctx = bucket->data;
115 /* Returned data will be from current position. */
116 *data = ctx->current;
117 serf_util_readline(&ctx->current, &ctx->remaining, acceptable, found);
119 /* See how much ctx->current moved forward. */
120 *len = ctx->current - *data;
122 return ctx->remaining ? APR_SUCCESS : APR_EOF;
125 static apr_status_t serf_simple_peek(serf_bucket_t *bucket,
129 simple_context_t *ctx = bucket->data;
131 /* return whatever we have left */
132 *data = ctx->current;
133 *len = ctx->remaining;
135 /* we returned everything this bucket will ever hold */
139 static void serf_simple_destroy(serf_bucket_t *bucket)
141 simple_context_t *ctx = bucket->data;
144 (*ctx->freefunc)(ctx->baton, ctx->original);
146 serf_default_destroy_and_data(bucket);
150 const serf_bucket_type_t serf_bucket_type_simple = {
153 serf_simple_readline,
154 serf_default_read_iovec,
155 serf_default_read_for_sendfile,
156 serf_default_read_bucket,