OSDN Git Service

* Added serf library.
[modchxj/mod_chxj.git] / src / serf / buckets / mmap_buckets.c
1 /* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
2  *
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
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15
16 #include <apr_pools.h>
17 #include <apr_mmap.h>
18
19 #include "serf.h"
20 #include "serf_bucket_util.h"
21
22
23 typedef struct {
24     apr_mmap_t *mmap;
25     void *current;
26     apr_off_t offset;
27     apr_off_t remaining;
28 } mmap_context_t;
29
30
31 SERF_DECLARE(serf_bucket_t *) serf_bucket_mmap_create(
32     apr_mmap_t *file_mmap,
33     serf_bucket_alloc_t *allocator)
34 {
35     mmap_context_t *ctx;
36
37     ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
38     ctx->mmap = file_mmap;
39     ctx->current = NULL;
40     ctx->offset = 0;
41     ctx->remaining = ctx->mmap->size;
42
43     return serf_bucket_create(&serf_bucket_type_mmap, allocator, ctx);
44 }
45
46 static apr_status_t serf_mmap_read(serf_bucket_t *bucket,
47                                      apr_size_t requested,
48                                      const char **data, apr_size_t *len)
49 {
50     mmap_context_t *ctx = bucket->data;
51
52     if (requested == SERF_READ_ALL_AVAIL || requested > ctx->remaining) {
53         *len = ctx->remaining;
54     }
55     else {
56         *len = requested;
57     }
58
59     /* ### Would it be faster to call this once and do the offset ourselves? */
60     apr_mmap_offset((void**)data, ctx->mmap, ctx->offset);
61
62     /* For the next read... */
63     ctx->offset += *len;
64     ctx->remaining -= *len;
65
66     if (ctx->remaining == 0) {
67         return APR_EOF;
68     }
69     return APR_SUCCESS;
70 }
71
72 static apr_status_t serf_mmap_readline(serf_bucket_t *bucket,
73                                          int acceptable, int *found,
74                                          const char **data, apr_size_t *len)
75 {
76     mmap_context_t *ctx = bucket->data;
77     const char *end;
78
79     /* ### Would it be faster to call this once and do the offset ourselves? */
80     apr_mmap_offset((void**)data, ctx->mmap, ctx->offset);
81     end = *data;
82
83     /* XXX An overflow is generated if we pass &ctx->remaining to readline.
84      * Not real clear why.
85      */
86     *len = ctx->remaining;
87
88     serf_util_readline(&end, len, acceptable, found);
89
90     *len = end - *data;
91
92     ctx->offset += *len;
93     ctx->remaining -= *len;
94
95     if (ctx->remaining == 0) {
96         return APR_EOF;
97     }
98     return APR_SUCCESS;
99 }
100
101 static apr_status_t serf_mmap_peek(serf_bucket_t *bucket,
102                                      const char **data,
103                                      apr_size_t *len)
104 {
105     /* Oh, bah. */
106     return APR_ENOTIMPL;
107 }
108
109 SERF_DECLARE_DATA const serf_bucket_type_t serf_bucket_type_mmap = {
110     "MMAP",
111     serf_mmap_read,
112     serf_mmap_readline,
113     serf_default_read_iovec,
114     serf_default_read_for_sendfile,
115     serf_default_read_bucket,
116     serf_mmap_peek,
117     serf_default_destroy_and_data,
118 };