// // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BEAST_EXAMPLE_FILE_BODY_H_INCLUDED #define BEAST_EXAMPLE_FILE_BODY_H_INCLUDED #include #include #include #include #include #include #include #include namespace beast { namespace http { struct file_body { using value_type = std::string; class reader { std::uint64_t size_ = 0; std::uint64_t offset_ = 0; std::string const& path_; FILE* file_ = nullptr; char buf_[4096]; std::size_t buf_len_; public: using is_deferred = std::true_type; using const_buffers_type = boost::asio::const_buffers_1; reader(reader&&) = default; reader(reader const&) = delete; reader& operator=(reader const&) = delete; template reader(message const& m) : path_(m.body) { } ~reader() { if(file_) fclose(file_); } void init(error_code& ec) { file_ = fopen(path_.c_str(), "rb"); if(! file_) ec = error_code{errno, system_category()}; else size_ = boost::filesystem::file_size(path_); } std::uint64_t content_length() const { return size_; } boost::optional> get(error_code& ec) { if(size_ - offset_ < sizeof(buf_)) buf_len_ = static_cast( size_ - offset_); else buf_len_ = sizeof(buf_); auto const nread = fread( buf_, 1, sizeof(buf_), file_); if(ferror(file_)) { ec = error_code(errno, system_category()); return boost::none; } BOOST_ASSERT(nread != 0); offset_ += nread; return {{const_buffers_type{buf_, nread}, offset_ >= size_}}; } }; }; } // http } // beast #endif