1 /* ====================================================================
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
18 * ====================================================================
21 #include <apr_pools.h>
24 #include "serf_bucket_util.h"
32 serf_simple_freefunc_t freefunc;
38 static void free_copied_data(void *baton, const char *data)
40 serf_bucket_mem_free(baton, (char*)data);
43 serf_bucket_t *serf_bucket_simple_create(
46 serf_simple_freefunc_t freefunc,
48 serf_bucket_alloc_t *allocator)
50 simple_context_t *ctx;
52 ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
53 ctx->original = ctx->current = data;
55 ctx->freefunc = freefunc;
56 ctx->baton = freefunc_baton;
58 return serf_bucket_create(&serf_bucket_type_simple, allocator, ctx);
61 serf_bucket_t *serf_bucket_simple_copy_create(
62 const char *data, apr_size_t len,
63 serf_bucket_alloc_t *allocator)
65 simple_context_t *ctx;
67 ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
69 ctx->original = ctx->current = serf_bucket_mem_alloc(allocator, len);
70 memcpy((char*)ctx->original, data, len);
73 ctx->freefunc = free_copied_data;
74 ctx->baton = allocator;
76 return serf_bucket_create(&serf_bucket_type_simple, allocator, ctx);
79 serf_bucket_t *serf_bucket_simple_own_create(
80 const char *data, apr_size_t len,
81 serf_bucket_alloc_t *allocator)
83 simple_context_t *ctx;
85 ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
87 ctx->original = ctx->current = data;
90 ctx->freefunc = free_copied_data;
91 ctx->baton = allocator;
93 return serf_bucket_create(&serf_bucket_type_simple, allocator, ctx);
96 static apr_status_t serf_simple_read(serf_bucket_t *bucket,
98 const char **data, apr_size_t *len)
100 simple_context_t *ctx = bucket->data;
102 if (requested == SERF_READ_ALL_AVAIL || requested > ctx->remaining)
103 requested = ctx->remaining;
105 *data = ctx->current;
108 ctx->current += requested;
109 ctx->remaining -= requested;
111 return ctx->remaining ? APR_SUCCESS : APR_EOF;
114 static apr_status_t serf_simple_readline(serf_bucket_t *bucket,
115 int acceptable, int *found,
116 const char **data, apr_size_t *len)
118 simple_context_t *ctx = bucket->data;
120 /* Returned data will be from current position. */
121 *data = ctx->current;
122 serf_util_readline(&ctx->current, &ctx->remaining, acceptable, found);
124 /* See how much ctx->current moved forward. */
125 *len = ctx->current - *data;
127 return ctx->remaining ? APR_SUCCESS : APR_EOF;
130 static apr_status_t serf_simple_peek(serf_bucket_t *bucket,
134 simple_context_t *ctx = bucket->data;
136 /* return whatever we have left */
137 *data = ctx->current;
138 *len = ctx->remaining;
140 /* we returned everything this bucket will ever hold */
144 static void serf_simple_destroy(serf_bucket_t *bucket)
146 simple_context_t *ctx = bucket->data;
149 (*ctx->freefunc)(ctx->baton, ctx->original);
151 serf_default_destroy_and_data(bucket);
155 const serf_bucket_type_t serf_bucket_type_simple = {
158 serf_simple_readline,
159 serf_default_read_iovec,
160 serf_default_read_for_sendfile,
161 serf_default_read_bucket,