]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/examples/file_body.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / Beast / examples / file_body.hpp
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 #ifndef BEAST_EXAMPLE_FILE_BODY_H_INCLUDED
9 #define BEAST_EXAMPLE_FILE_BODY_H_INCLUDED
10
11 #include <beast/core/error.hpp>
12 #include <beast/http/message.hpp>
13 #include <boost/asio/buffer.hpp>
14 #include <boost/assert.hpp>
15 #include <boost/filesystem.hpp>
16 #include <cstdio>
17 #include <cstdint>
18
19 namespace beast {
20 namespace http {
21
22 struct file_body
23 {
24 using value_type = std::string;
25
26 class writer
27 {
28 std::uint64_t size_ = 0;
29 std::uint64_t offset_ = 0;
30 std::string const& path_;
31 FILE* file_ = nullptr;
32 char buf_[4096];
33 std::size_t buf_len_;
34
35 public:
36 writer(writer const&) = delete;
37 writer& operator=(writer const&) = delete;
38
39 template<bool isRequest, class Fields>
40 writer(message<isRequest,
41 file_body, Fields> const& m) noexcept
42 : path_(m.body)
43 {
44 }
45
46 ~writer()
47 {
48 if(file_)
49 fclose(file_);
50 }
51
52 void
53 init(error_code& ec) noexcept
54 {
55 file_ = fopen(path_.c_str(), "rb");
56 if(! file_)
57 ec = error_code{errno,
58 system_category()};
59 else
60 size_ = boost::filesystem::file_size(path_);
61 }
62
63 std::uint64_t
64 content_length() const noexcept
65 {
66 return size_;
67 }
68
69 template<class WriteFunction>
70 bool
71 write(error_code& ec, WriteFunction&& wf) noexcept
72 {
73 if(size_ - offset_ < sizeof(buf_))
74 buf_len_ = static_cast<std::size_t>(
75 size_ - offset_);
76 else
77 buf_len_ = sizeof(buf_);
78 auto const nread = fread(
79 buf_, 1, sizeof(buf_), file_);
80 if(ferror(file_))
81 {
82 ec = error_code(errno,
83 system_category());
84 return true;
85 }
86 BOOST_ASSERT(nread != 0);
87 offset_ += nread;
88 wf(boost::asio::buffer(buf_, nread));
89 return offset_ >= size_;
90 }
91 };
92 };
93
94 } // http
95 } // beast
96
97 #endif