src/detail/send_file.cpp

100.0% Lines (2/2) 100.0% List of functions (1/1) 100.0% Branches (1/1)
send_file.cpp
f(x) Functions (1)
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Mohammad Nejati
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 // Official repository: https://github.com/cppalliance/burl
8 //
9
10 #include "send_file.hpp"
11
12 #include "util.hpp"
13
14 #include <boost/burl/error.hpp>
15 #include <boost/capy/cond.hpp>
16 #include <boost/capy/ex/this_coro.hpp>
17 #include <boost/corosio/file_base.hpp>
18 #include <boost/corosio/stream_file.hpp>
19 #include <boost/http/io/any_buffer_sink.hpp>
20
21 #include <system_error>
22
23 namespace boost
24 {
25 namespace burl
26 {
27 namespace detail
28 {
29
30 capy::io_task<>
31
1/1
✓ Branch 1 taken 10 times.
10x send_file(
32 http::any_buffer_sink& sink,
33 std::filesystem::path const& path,
34 std::uint64_t size,
35 bool call_eof)
36 {
37 corosio::stream_file f(co_await capy::this_coro::executor);
38 if(auto ec = f.open(path, corosio::file_base::read_only))
39 co_return { ec };
40
41 auto remaining = size;
42 while(remaining > 0)
43 {
44 capy::mutable_buffer arr[2];
45 auto dst = sink.prepare(arr);
46 if(dst.empty())
47 {
48 if(auto [ec] = co_await sink.commit(0); ec)
49 co_return { ec };
50 continue;
51 }
52
53 auto [rec, n] = co_await f.read_some(dst);
54
55 auto take = clamp(remaining, n);
56 if(take)
57 {
58 if(call_eof && take == remaining)
59 {
60 if(auto [ec] = co_await sink.commit_eof(take); ec)
61 co_return { ec };
62 }
63 if(auto [ec] = co_await sink.commit(take); ec)
64 co_return { ec };
65 remaining -= take;
66 }
67
68 if(remaining == 0)
69 break;
70 if(rec == capy::cond::eof)
71 co_return { error::file_changed };
72 if(rec)
73 co_return { rec };
74 }
75
76 co_return {};
77 20x }
78
79 } // namespace detail
80 } // namespace burl
81 } // namespace boost
82