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/capy/io/any_buffer_sink.hpp>
18 #include <boost/corosio/file_base.hpp>
19 #include <boost/corosio/stream_file.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 7 times.
7x send_file(
32 capy::any_buffer_sink& sink,
33 std::filesystem::path const& path,
34 std::uint64_t size)
35 {
36 corosio::stream_file f(co_await capy::this_coro::executor);
37 // TODO: switch to a non-throwing open() overload once available.
38 try
39 {
40 f.open(path, corosio::file_base::read_only);
41 }
42 catch(std::system_error const& e)
43 {
44 co_return { e.code() };
45 }
46
47 auto remaining = size;
48 while(remaining > 0)
49 {
50 capy::mutable_buffer arr[2];
51 auto dst = sink.prepare(arr);
52 if(dst.empty())
53 {
54 if(auto [ec] = co_await sink.commit(0); ec)
55 co_return { ec };
56 continue;
57 }
58
59 auto [rec, n] = co_await f.read_some(dst);
60
61 auto take = clamp(remaining, n);
62 if(take)
63 {
64 if(auto [ec] = co_await sink.commit(take); ec)
65 co_return { ec };
66 remaining -= take;
67 }
68
69 if(remaining == 0)
70 break;
71 if(rec == capy::cond::eof)
72 co_return { error::file_changed };
73 if(rec)
74 co_return { rec };
75 }
76
77 co_return {};
78 14x }
79
80 } // namespace detail
81 } // namespace burl
82 } // namespace boost
83