TLA Line data Source code
1 : //
2 : // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2024 Mohammad Nejati
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/cppalliance/http
9 : //
10 :
11 : #include "src/detail/filter.hpp"
12 :
13 : #include <boost/capy/buffers/buffer_slice.hpp>
14 : #include <boost/capy/buffers/front.hpp>
15 :
16 : namespace boost {
17 : namespace http {
18 : namespace detail {
19 :
20 : namespace {
21 :
22 : // Returns true if the slice's current data view contains at most one
23 : // non-empty buffer (i.e., we are processing the last logical chunk).
24 : template<class Slice>
25 MIS 0 : bool single_or_empty(Slice const& s)
26 : {
27 0 : auto d = s.data();
28 0 : auto it = d.begin();
29 0 : auto const end_it = d.end();
30 0 : if(it == end_it)
31 0 : return true;
32 0 : ++it;
33 0 : return it == end_it;
34 : }
35 :
36 : } // anonymous
37 :
38 : auto
39 0 : filter::
40 : process(
41 : boost::span<const capy::mutable_buffer> out_seq,
42 : std::array<capy::const_buffer, 2> in_seq,
43 : bool more) -> results
44 : {
45 0 : auto out = capy::buffer_slice(out_seq);
46 0 : auto in = capy::buffer_slice(in_seq);
47 :
48 0 : results rv;
49 0 : bool p_more = true;
50 : for(;;)
51 : {
52 0 : if(!more && p_more && single_or_empty(in))
53 : {
54 0 : if(capy::buffer_size(out.data()) < min_out_buffer())
55 : {
56 0 : rv.out_short = true;
57 0 : return rv;
58 : }
59 0 : p_more = false;
60 : }
61 :
62 0 : auto ob = capy::front(out.data());
63 0 : auto ib = capy::front(in.data());
64 0 : auto rs = do_process(ob, ib, p_more);
65 :
66 0 : rv.in_bytes += rs.in_bytes;
67 0 : rv.out_bytes += rs.out_bytes;
68 :
69 0 : if(rs.ec)
70 : {
71 0 : rv.ec = rs.ec;
72 0 : return rv;
73 : }
74 :
75 0 : if(rs.finished)
76 : {
77 0 : rv.finished = true;
78 0 : return rv;
79 : }
80 :
81 0 : out.remove_prefix(rs.out_bytes);
82 0 : in.remove_prefix(rs.in_bytes);
83 :
84 0 : if(capy::buffer_size(out.data()) == 0)
85 0 : return rv;
86 :
87 0 : if(capy::buffer_size(in.data()) == 0 && rs.out_bytes < ob.size())
88 0 : return rv;
89 0 : }
90 : }
91 :
92 : } // detail
93 : } // http
94 : } // boost
|