]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/libsvn_ra_serf/eagain_bucket.c
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / libsvn_ra_serf / eagain_bucket.c
1 /*
2  * eagain_bucket.c :  a serf bucket that handles slowing down data
3  *                   for specific readers that would have unwanted
4  *                   behavior if they read everything too fast
5  * ====================================================================
6  *    Licensed to the Apache Software Foundation (ASF) under one
7  *    or more contributor license agreements.  See the NOTICE file
8  *    distributed with this work for additional information
9  *    regarding copyright ownership.  The ASF licenses this file
10  *    to you under the Apache License, Version 2.0 (the
11  *    "License"); you may not use this file except in compliance
12  *    with the License.  You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  *    Unless required by applicable law or agreed to in writing,
17  *    software distributed under the License is distributed on an
18  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  *    KIND, either express or implied.  See the License for the
20  *    specific language governing permissions and limitations
21  *    under the License.
22  * ====================================================================
23  */
24
25 #include <serf.h>
26 #include <serf_bucket_util.h>
27
28 #include "svn_private_config.h"
29
30 #include "ra_serf.h"
31
32 typedef struct eagain_baton_t
33 {
34   const char *data;
35   apr_size_t remaining;
36 } eagain_baton_t;
37
38 static apr_status_t
39 eagain_bucket_read(serf_bucket_t *bucket,
40                    apr_size_t requested,
41                    const char **data,
42                    apr_size_t *len)
43 {
44   eagain_baton_t *eab = bucket->data;
45
46   if (eab->remaining > 0)
47     {
48       *data = eab->data;
49       if (requested > eab->remaining || requested == SERF_READ_ALL_AVAIL)
50         {
51           *len = eab->remaining;
52           eab->data = NULL;
53           eab->remaining = 0;
54         }
55       else
56         {
57           *len = requested;
58           eab->data += requested;
59           eab->remaining -= requested;
60         }
61
62       if (eab->remaining)
63         return APR_SUCCESS;
64     }
65
66   return APR_EAGAIN;
67 }
68
69
70 static apr_status_t
71 eagain_bucket_readline(serf_bucket_t *bucket,
72                        int acceptable,
73                        int *found,
74                        const char **data,
75                        apr_size_t *len)
76 {
77   /* ### for now, we know callers won't use this function.  */
78   svn_error_clear(svn_error__malfunction(TRUE, __FILE__, __LINE__,
79                                          "Not implemented."));
80   return APR_ENOTIMPL;
81 }
82
83
84 static apr_status_t
85 eagain_bucket_peek(serf_bucket_t *bucket,
86                    const char **data,
87                    apr_size_t *len)
88 {
89   const eagain_baton_t *eab = bucket->data;
90
91   *data = eab->data ? eab->data : "";
92   *len = eab->remaining;
93
94   return APR_SUCCESS;
95 }
96
97
98 static const serf_bucket_type_t delay_bucket_vtable = {
99     "BUF-EAGAIN",
100     eagain_bucket_read,
101     eagain_bucket_readline,
102     serf_default_read_iovec,
103     serf_default_read_for_sendfile,
104     serf_default_read_bucket,
105     eagain_bucket_peek,
106     serf_default_destroy_and_data,
107 };
108
109
110 serf_bucket_t *
111 svn_ra_serf__create_bucket_with_eagain(const char *data,
112                                        apr_size_t len,
113                                        serf_bucket_alloc_t *allocator)
114 {
115   eagain_baton_t *eab;
116
117   eab = serf_bucket_mem_alloc(allocator, sizeof(*eab));
118   eab->data = data;
119   eab->remaining = len;
120
121   return serf_bucket_create(&delay_bucket_vtable, allocator, eab);
122 }