2 * sb_bucket.c : a serf bucket that wraps a spillbuf
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
25 #include <serf_bucket_util.h>
27 #include "svn_private_config.h"
28 #include "private/svn_subr_private.h"
32 #define SB_BLOCKSIZE 1024
33 #define SB_MAXSIZE 32768
38 svn_spillbuf_t *spillbuf;
43 apr_pool_t *scratch_pool;
48 svn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf,
50 apr_pool_t *result_pool,
51 apr_pool_t *scratch_pool)
53 *spillbuf = svn_spillbuf__create(SB_BLOCKSIZE, SB_MAXSIZE, result_pool);
55 /* Copy all data from the bucket into the spillbuf. */
62 status = serf_bucket_read(bkt, SERF_READ_ALL_AVAIL, &data, &len);
64 if (status != APR_SUCCESS && status != APR_EOF)
65 return svn_ra_serf__wrap_err(status, _("Failed to read the request"));
67 SVN_ERR(svn_spillbuf__write(*spillbuf, data, len, scratch_pool));
69 if (status == APR_EOF)
78 sb_bucket_read(serf_bucket_t *bucket, apr_size_t requested,
79 const char **data, apr_size_t *len)
81 struct sbb_baton *sbb = bucket->data;
88 if (requested < sbb->hold_len)
91 sbb->holding += requested;
92 sbb->hold_len -= requested;
96 /* Return whatever we're holding, and then forget (consume) it. */
102 err = svn_spillbuf__read(data, len, sbb->spillbuf, sbb->scratch_pool);
103 svn_pool_clear(sbb->scratch_pool);
105 /* ### do something with this */
106 svn_error_clear(err);
108 /* The spillbuf may have returned more than requested. Stash any extra
109 into our holding area. */
110 if (requested < *len)
112 sbb->holding = *data + requested;
113 sbb->hold_len = *len - requested;
117 return *data == NULL ? APR_EOF : APR_SUCCESS;
122 sb_bucket_readline(serf_bucket_t *bucket, int acceptable,
124 const char **data, apr_size_t *len)
126 /* ### for now, we know callers won't use this function. */
127 svn_error_clear(svn_error__malfunction(TRUE, __FILE__, __LINE__,
128 "Not implemented."));
134 sb_bucket_peek(serf_bucket_t *bucket,
135 const char **data, apr_size_t *len)
137 struct sbb_baton *sbb = bucket->data;
140 /* If we're not holding any data, then fill it. */
141 if (sbb->holding == NULL)
143 err = svn_spillbuf__read(&sbb->holding, &sbb->hold_len, sbb->spillbuf,
145 svn_pool_clear(sbb->scratch_pool);
147 /* ### do something with this */
148 svn_error_clear(err);
151 /* Return the data we are (now) holding. */
152 *data = sbb->holding;
153 *len = sbb->hold_len;
155 return *data == NULL ? APR_EOF : APR_SUCCESS;
159 static const serf_bucket_type_t sb_bucket_vtable = {
163 serf_default_read_iovec,
164 serf_default_read_for_sendfile,
165 serf_default_read_bucket,
167 serf_default_destroy_and_data,
172 svn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf,
173 serf_bucket_alloc_t *allocator,
174 apr_pool_t *result_pool,
175 apr_pool_t *scratch_pool)
177 struct sbb_baton *sbb;
179 sbb = serf_bucket_mem_alloc(allocator, sizeof(*sbb));
180 sbb->spillbuf = spillbuf;
182 sbb->scratch_pool = svn_pool_create(result_pool);
184 return serf_bucket_create(&sb_bucket_vtable, allocator, sbb);