]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) | |
3 | ||
4 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ] | |
7 | ||
8 | [section:Reader Reader requirements] | |
9 | ||
10 | Parsers provided by the implementation will construct the corresponding | |
11 | `reader` object during parsing. This customization point allows the | |
12 | Body to determine the strategy for storing incoming message body data. | |
13 | Readers come in two flavors, direct and indirect: | |
14 | ||
15 | Direct readers provide a buffer to callers, in which body data is placed. | |
16 | This type of reader is used when the bytes corresponding to the body data | |
17 | are stored without transformation. The parse algorithm performs stream or | |
18 | socket reads directly into the reader-provided buffer, hence the name | |
19 | "direct." This model avoids an unnecessary buffer copy. An example of | |
20 | a [*Body] type with a direct reader is | |
21 | [link beast.ref.http__string_body `string_body`]. | |
22 | ||
23 | Indirect readers are passed body data in a buffer managed by the parser | |
24 | algorithm. This reader is appropriate when the body data is transformed | |
25 | or not otherwised stored verbatim. Some examples of when an indirect | |
26 | reader is appropriate: | |
27 | ||
28 | * When bytes corresponding to the body are written to a file | |
29 | as they are parsed. | |
30 | ||
31 | * The content of the message is JSON, which is parsed as it is | |
32 | being read in, and stored in a structured, hierarchical format. | |
33 | ||
34 | In the tables below: | |
35 | ||
36 | * `X` denotes a type meeting the requirements of [*`Reader`]. | |
37 | ||
38 | * `a` denotes a value of type `X`. | |
39 | ||
40 | * `n` is a value convertible to `std::size_t` without loss of precision. | |
41 | ||
42 | * `v` is a value convertible to `std::uint64_t` without loss of precision. | |
43 | ||
44 | * `s` is a value of type `boost::string_ref`. | |
45 | ||
46 | * `ec` is a value of type [link beast.ref.error_code `error_code&`]. | |
47 | ||
48 | * `m` denotes a value of type `message&` where | |
49 | `std::is_same<decltype(m.body), Body::value_type>::value == true`. | |
50 | ||
51 | [table Direct Reader requirements | |
52 | [[operation] [type] [semantics, pre/post-conditions]] | |
53 | [ | |
54 | [`X::is_direct`] | |
55 | [`bool`] | |
56 | [ | |
57 | This static constant must be set to `true` to indicate that | |
58 | the reader is a direct reader. | |
59 | ] | |
60 | ] | |
61 | [ | |
62 | [`X::mutable_buffers_type`] | |
63 | [] | |
64 | [ | |
65 | This member type must be present, and meet the requirements | |
66 | of [*MutableBufferSequence]. It represents the type of | |
67 | the writable buffers returned by the reader, in which | |
68 | bytes representing the body are stored by the implementation. | |
69 | ] | |
70 | ] | |
71 | [ | |
72 | [`X a{m};`] | |
73 | [] | |
74 | [ | |
75 | `a` is constructible from `m`. The lifetime of `m` is guaranteed | |
76 | to end no earlier than after `a` is destroyed. The constructor | |
77 | will be called after all headers have been stored in `m`, and | |
78 | just before parsing bytes corresponding to the body for messages | |
79 | whose semantics indicate that a body is present with non-zero | |
80 | length. | |
81 | ] | |
82 | ] | |
83 | [ | |
84 | [`a.init()`] | |
85 | [] | |
86 | [ | |
87 | This function is called once before any bytes corresponding | |
88 | to the body are presented to the reader, for messages whose | |
89 | body is determined by the end-of-file marker on a stream, | |
90 | or for messages where the chunked Transfer-Encoding is | |
91 | specified. | |
92 | ] | |
93 | ] | |
94 | [ | |
95 | [`a.init(v)`] | |
96 | [] | |
97 | [ | |
98 | This function is called once before any bytes corresponding | |
99 | to the body are presented to the reader, for messages where | |
100 | the Content-Length is specified. The value of `v` will be | |
101 | set to the number of bytes indicated by the content length. | |
102 | ] | |
103 | ] | |
104 | [ | |
105 | [`a.prepare(n)`] | |
106 | [`mutable_buffers_type`] | |
107 | [ | |
108 | The implementation calls this function to obtain a mutable | |
109 | buffer sequence of up to `n` bytes in size in which to place | |
110 | data corresponding to the body. The buffer returned must | |
111 | be at least one byte in size, and may be smaller than `n`. | |
112 | ] | |
113 | ] | |
114 | [ | |
115 | [`a.commit(n)`] | |
116 | [] | |
117 | [ | |
118 | The implementation calls this function to indicate to the | |
119 | reader that `n` bytes of data have been successfully placed | |
120 | into the buffer obtained through a prior call to `prepare`. | |
121 | The value of `n` will be less than or equal to the size of | |
122 | the buffer returned in the previous call to `prepare`. | |
123 | ] | |
124 | ] | |
125 | [ | |
126 | [`a.finish()`] | |
127 | [] | |
128 | [ | |
129 | This function is called after all the bytes corresponding | |
130 | to the body have been written to the buffers and committed. | |
131 | ] | |
132 | ] | |
133 | ] | |
134 | ||
135 | [table Indirect Reader requirements | |
136 | [[operation] [type] [semantics, pre/post-conditions]] | |
137 | [ | |
138 | [`X::is_direct`] | |
139 | [`bool`] | |
140 | [ | |
141 | This static constant must be set to `false` to indicate that | |
142 | the reader is an indirect reader. | |
143 | ] | |
144 | ] | |
145 | [ | |
146 | [`X a{m};`] | |
147 | [] | |
148 | [ | |
149 | `a` is constructible from `m`. The lifetime of `m` is guaranteed | |
150 | to end no earlier than after `a` is destroyed. The constructor | |
151 | will be called after all headers have been stored in `m`, and | |
152 | just before parsing bytes corresponding to the body for messages | |
153 | whose semantics indicate that a body is present with non-zero | |
154 | length. | |
155 | ] | |
156 | ] | |
157 | [ | |
158 | [`a.init(ec)`] | |
159 | [] | |
160 | [ | |
161 | This function is called once before any bytes corresponding | |
162 | to the body are presented to the reader, for messages whose | |
163 | body is determined by the end-of-file market on a stream, | |
164 | or for messages where the chunked Transfer-Encoding is | |
165 | specified. | |
166 | If `ec` is set before returning, parsing will stop | |
167 | and the error will be returned to the caller. | |
168 | ||
169 | ] | |
170 | ] | |
171 | [ | |
172 | [`a.init(v,ec)`] | |
173 | [] | |
174 | [ | |
175 | This function is called once before any bytes corresponding | |
176 | to the body are presented to the reader, for messages where | |
177 | the Content-Length is specified. The value of `v` will be | |
178 | set to the number of bytes indicated by the content length. | |
179 | If `ec` is set before returning, parsing will stop | |
180 | and the error will be returned to the caller. | |
181 | ] | |
182 | ] | |
183 | [ | |
184 | [`a.write(s,ec)`] | |
185 | [] | |
186 | [ | |
187 | The implementation calls this function with `s` containing | |
188 | bytes corresponding to the body, after removing any present | |
189 | chunked encoding transformation. | |
190 | If `ec` is set before returning, parsing will stop | |
191 | and the error will be returned to the caller. | |
192 | ] | |
193 | ] | |
194 | [ | |
195 | [`a.finish(ec)`] | |
196 | [] | |
197 | [ | |
198 | This function is called after all the bytes corresponding | |
199 | to the body have been written to the buffers and committed. | |
200 | If `ec` is set before returning, parsing will stop | |
201 | and the error will be returned to the caller. | |
202 | ] | |
203 | ] | |
204 | ] | |
205 | [note | |
206 | Definitions for required `Reader` member functions should be declared | |
207 | inline so the generated code can become part of the implementation. | |
208 | ] | |
209 | ||
210 | [endsect] |