add a cmake option to switch between std and boost filesystem

master
Chunting Gu 4 years ago
parent 39719c4ded
commit df96f969bc

@ -25,11 +25,13 @@ option(BUILD_UNITTEST "Build unit test?" OFF)
option(BUILD_EXAMPLES "Build examples?" ON) option(BUILD_EXAMPLES "Build examples?" ON)
option(BUILD_QT_EXAMPLES "Build Qt application examples?" OFF) option(BUILD_QT_EXAMPLES "Build Qt application examples?" OFF)
set(WEBCC_ENABLE_LOG 1 CACHE STRING "Enable logging? (1:Yes, 0:No)") set(WEBCC_ENABLE_LOG 1 CACHE STRING "Enable logging? (1:Yes, 0:No)")
set(WEBCC_ENABLE_SSL 0 CACHE STRING "Enable SSL/HTTPS (need OpenSSL)? (1:Yes, 0:No)") set(WEBCC_ENABLE_SSL 0 CACHE STRING "Enable SSL/HTTPS (need OpenSSL)? (1:Yes, 0:No)")
set(WEBCC_ENABLE_GZIP 0 CACHE STRING "Enable gzip compression (need Zlib)? (1:Yes, 0:No)") set(WEBCC_ENABLE_GZIP 0 CACHE STRING "Enable gzip compression (need Zlib)? (1:Yes, 0:No)")
set(WEBCC_LOG_LEVEL 2 CACHE STRING "Log level (0:VERB, 1:INFO, 2:USER, 3:WARN or 4:ERRO)") set(WEBCC_LOG_LEVEL 2 CACHE STRING "Log level (0:VERB, 1:INFO, 2:USER, 3:WARN or 4:ERRO)")
set(WEBCC_USE_STD_FILESYSTEM 1 CACHE STRING "Use C++17 filesystem? (1:Yes, 0:No)")
if(BUILD_UNITTEST) if(BUILD_UNITTEST)
enable_testing() enable_testing()
@ -42,16 +44,30 @@ if(WIN32)
endif() endif()
# C++ standard requirements. # C++ standard requirements.
set(CMAKE_CXX_STANDARD 11)
if(WEBCC_USE_STD_FILESYSTEM)
set(CMAKE_CXX_STANDARD 17)
else()
set(CMAKE_CXX_STANDARD 11)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
# Boost # Boost
set(BOOST_COMPONENTS system date_time)
if(NOT WEBCC_USE_STD_FILESYSTEM)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} filesystem)
endif()
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON) set(Boost_USE_MULTITHREADED ON)
find_package(Boost 1.66.0 REQUIRED COMPONENTS system date_time filesystem) find_package(Boost 1.66.0 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
if(Boost_FOUND) if(Boost_FOUND)
message(STATUS "Boost version: ${Boost_VERSION}") message(STATUS "Boost version: ${Boost_VERSION}")
message(STATUS "Boost libraries: ${Boost_LIBRARIES}")
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
endif() endif()

@ -2,18 +2,15 @@
#include <iostream> #include <iostream>
#include "boost/algorithm/string.hpp" #include "boost/algorithm/string.hpp"
#include "boost/filesystem/fstream.hpp"
#include "boost/filesystem/operations.hpp"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "json/json.h" #include "json/json.h"
#include "webcc/client_session.h" #include "webcc/client_session.h"
#include "webcc/fs.h"
#include "webcc/string.h" #include "webcc/string.h"
namespace bfs = boost::filesystem;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// JSON helper functions (based on jsoncpp). // JSON helper functions (based on jsoncpp).
@ -181,15 +178,15 @@ TEST(ClientTest, Get_Jpeg_Stream) {
EXPECT_TRUE(!file_body->path().empty()); EXPECT_TRUE(!file_body->path().empty());
// Backup the path of the temp file. // Backup the path of the temp file.
const bfs::path ori_path = file_body->path(); const webcc::fs::path ori_path = file_body->path();
const bfs::path new_path("./wolf.jpeg"); const webcc::fs::path new_path("./wolf.jpeg");
bool moved = file_body->Move(new_path); bool moved = file_body->Move(new_path);
EXPECT_TRUE(moved); EXPECT_TRUE(moved);
EXPECT_TRUE(bfs::exists(new_path)); EXPECT_TRUE(webcc::fs::exists(new_path));
// The file in the original path should not exist any more. // The file in the original path should not exist any more.
EXPECT_TRUE(!bfs::exists(ori_path)); EXPECT_TRUE(!webcc::fs::exists(ori_path));
// After move, the original path should be reset. // After move, the original path should be reset.
EXPECT_TRUE(file_body->path().empty()); EXPECT_TRUE(file_body->path().empty());
@ -205,7 +202,7 @@ TEST(ClientTest, Get_Jpeg_Stream_NoMove) {
webcc::ClientSession session; webcc::ClientSession session;
try { try {
bfs::path ori_path; webcc::fs::path ori_path;
{ {
auto r = session.Send(webcc::RequestBuilder{}. auto r = session.Send(webcc::RequestBuilder{}.
@ -223,7 +220,7 @@ TEST(ClientTest, Get_Jpeg_Stream_NoMove) {
} }
// The temp file should be deleted. // The temp file should be deleted.
EXPECT_TRUE(!bfs::exists(ori_path)); EXPECT_TRUE(!webcc::fs::exists(ori_path));
} catch (const webcc::Error& error) { } catch (const webcc::Error& error) {
std::cerr << error << std::endl; std::cerr << error << std::endl;
@ -298,22 +295,22 @@ TEST(ClientTest, Post) {
} }
} }
static bfs::path GenerateTempFile(const std::string& data) { static webcc::fs::path GenerateTempFile(const std::string& data) {
try { try {
bfs::path path = bfs::temp_directory_path() / webcc::RandomString(10); webcc::fs::path path = webcc::fs::temp_directory_path() / webcc::RandomString(10);
bfs::ofstream ofs; webcc::fs::ofstream ofs;
ofs.open(path, std::ios::binary); ofs.open(path, std::ios::binary);
if (ofs.fail()) { if (ofs.fail()) {
return bfs::path{}; return webcc::fs::path{};
} }
ofs << data; ofs << data;
return path; return path;
} catch (const bfs::filesystem_error&) { } catch (const webcc::fs::filesystem_error&) {
return bfs::path{}; return webcc::fs::path{};
} }
} }
@ -344,8 +341,8 @@ TEST(ClientTest, Post_FileBody) {
} }
// Remove the temp file. // Remove the temp file.
boost::system::error_code ec; webcc::fs::error_code ec;
bfs::remove(path, ec); webcc::fs::remove(path, ec);
} }
#if WEBCC_ENABLE_GZIP #if WEBCC_ENABLE_GZIP

@ -3,14 +3,11 @@
#include <iostream> #include <iostream>
#include "boost/algorithm/string.hpp" #include "boost/algorithm/string.hpp"
#include "boost/filesystem/operations.hpp"
#include "json/json.h" #include "json/json.h"
#include "book_json.h" #include "book_json.h"
namespace bfs = boost::filesystem;
BookClient::BookClient(const std::string& url, int timeout) BookClient::BookClient(const std::string& url, int timeout)
: url_(url), session_(timeout) { : url_(url), session_(timeout) {
// Default Content-Type for requests with a body. // Default Content-Type for requests with a body.
@ -127,7 +124,7 @@ bool BookClient::Delete(const std::string& id) {
} }
} }
bool BookClient::GetPhoto(const std::string& id, const bfs::path& path) { bool BookClient::GetPhoto(const std::string& id, const webcc::fs::path& path) {
try { try {
auto r = session_.Send(WEBCC_GET(url_). auto r = session_.Send(WEBCC_GET(url_).
Path("books").Path(id).Path("photo")(), Path("books").Path(id).Path("photo")(),
@ -147,7 +144,7 @@ bool BookClient::GetPhoto(const std::string& id, const bfs::path& path) {
} }
} }
bool BookClient::SetPhoto(const std::string& id, const bfs::path& path) { bool BookClient::SetPhoto(const std::string& id, const webcc::fs::path& path) {
try { try {
if (!CheckPhoto(path)) { if (!CheckPhoto(path)) {
return false; return false;
@ -169,12 +166,12 @@ bool BookClient::SetPhoto(const std::string& id, const bfs::path& path) {
} }
} }
bool BookClient::CheckPhoto(const bfs::path& photo) { bool BookClient::CheckPhoto(const webcc::fs::path& photo) {
if (photo.empty()) { if (photo.empty()) {
return false; return false;
} }
if (!bfs::is_regular_file(photo) || !bfs::exists(photo)) { if (!webcc::fs::is_regular_file(photo) || !webcc::fs::exists(photo)) {
return false; return false;
} }

@ -4,11 +4,10 @@
#include <list> #include <list>
#include <string> #include <string>
#include "boost/filesystem/path.hpp"
#include "json/json-forwards.h" #include "json/json-forwards.h"
#include "webcc/client_session.h" #include "webcc/client_session.h"
#include "webcc/fs.h"
#include "book.h" #include "book.h"
@ -29,13 +28,13 @@ public:
bool Delete(const std::string& id); bool Delete(const std::string& id);
// Get photo, save to the given path. // Get photo, save to the given path.
bool GetPhoto(const std::string& id, const boost::filesystem::path& path); bool GetPhoto(const std::string& id, const webcc::fs::path& path);
// Set photo using the file of the given path. // Set photo using the file of the given path.
bool SetPhoto(const std::string& id, const boost::filesystem::path& path); bool SetPhoto(const std::string& id, const webcc::fs::path& path);
private: private:
bool CheckPhoto(const boost::filesystem::path& photo); bool CheckPhoto(const webcc::fs::path& photo);
// Check HTTP response status. // Check HTTP response status.
bool CheckStatus(webcc::ResponsePtr response, int expected_status); bool CheckStatus(webcc::ResponsePtr response, int expected_status);

@ -1,13 +1,10 @@
#include <iostream> #include <iostream>
#include "boost/filesystem/operations.hpp" #include "webcc/fs.h"
#include "webcc/logger.h" #include "webcc/logger.h"
#include "book_client.h" #include "book_client.h"
namespace bfs = boost::filesystem;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void PrintSeparator() { void PrintSeparator() {
@ -39,8 +36,8 @@ int main(int argc, char* argv[]) {
std::string url = argv[1]; std::string url = argv[1];
bfs::path photo_dir = argv[2]; webcc::fs::path photo_dir = argv[2];
if (!bfs::is_directory(photo_dir) || !bfs::exists(photo_dir)) { if (!webcc::fs::is_directory(photo_dir) || !webcc::fs::exists(photo_dir)) {
std::cerr << "Invalid photo dir!" << std::endl; std::cerr << "Invalid photo dir!" << std::endl;
return 1; return 1;
} }

@ -1,14 +1,11 @@
#include <iostream> #include <iostream>
#include "boost/filesystem/operations.hpp" #include "webcc/fs.h"
#include "webcc/logger.h" #include "webcc/logger.h"
#include "webcc/server.h" #include "webcc/server.h"
#include "views.h" #include "views.h"
namespace bfs = boost::filesystem;
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if (argc < 3) { if (argc < 3) {
std::cout << "usage: book_server <port> <upload_dir>" << std::endl; std::cout << "usage: book_server <port> <upload_dir>" << std::endl;
@ -21,16 +18,16 @@ int main(int argc, char* argv[]) {
std::uint16_t port = static_cast<std::uint16_t>(std::atoi(argv[1])); std::uint16_t port = static_cast<std::uint16_t>(std::atoi(argv[1]));
bfs::path upload_dir = argv[2]; webcc::fs::path upload_dir = argv[2];
if (!bfs::is_directory(upload_dir) || !bfs::exists(upload_dir)) { if (!webcc::fs::is_directory(upload_dir) || !webcc::fs::exists(upload_dir)) {
std::cerr << "Invalid upload dir!" << std::endl; std::cerr << "Invalid upload dir!" << std::endl;
return 1; return 1;
} }
// Add a sub-dir for book photos. // Add a sub-dir for book photos.
bfs::path photo_dir = upload_dir / "books"; webcc::fs::path photo_dir = upload_dir / "books";
if (!bfs::exists(photo_dir)) { if (!webcc::fs::exists(photo_dir)) {
bfs::create_directory(photo_dir); webcc::fs::create_directory(photo_dir);
} }
std::cout << "Book photos will be saved to: " << photo_dir << std::endl; std::cout << "Book photos will be saved to: " << photo_dir << std::endl;

@ -1,7 +1,5 @@
#include "views.h" #include "views.h"
#include "boost/filesystem/operations.hpp"
#include "json/json.h" #include "json/json.h"
#include "webcc/response_builder.h" #include "webcc/response_builder.h"
@ -10,8 +8,6 @@
#include "book_db.h" #include "book_db.h"
#include "book_json.h" #include "book_json.h"
namespace bfs = boost::filesystem;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static BookDB g_book_db; static BookDB g_book_db;
@ -57,7 +53,7 @@ webcc::ResponsePtr BookListView::Post(webcc::RequestPtr request) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
BookDetailView::BookDetailView(bfs::path photo_dir) BookDetailView::BookDetailView(webcc::fs::path photo_dir)
: photo_dir_(std::move(photo_dir)) { : photo_dir_(std::move(photo_dir)) {
} }
@ -125,8 +121,8 @@ webcc::ResponsePtr BookDetailView::Delete(webcc::RequestPtr request) {
// Delete the photo from file system. // Delete the photo from file system.
if (!photo_name.empty()) { if (!photo_name.empty()) {
boost::system::error_code ec; webcc::fs::error_code ec;
bfs::remove(photo_dir_ / photo_name, ec); webcc::fs::remove(photo_dir_ / photo_name, ec);
} }
return webcc::ResponseBuilder{}.OK()(); return webcc::ResponseBuilder{}.OK()();
@ -134,7 +130,7 @@ webcc::ResponsePtr BookDetailView::Delete(webcc::RequestPtr request) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
BookPhotoView::BookPhotoView(bfs::path photo_dir) BookPhotoView::BookPhotoView(webcc::fs::path photo_dir)
: photo_dir_(std::move(photo_dir)) { : photo_dir_(std::move(photo_dir)) {
} }
@ -164,8 +160,8 @@ webcc::ResponsePtr BookPhotoView::Get(webcc::RequestPtr request) {
return webcc::ResponseBuilder{}.NotFound()(); return webcc::ResponseBuilder{}.NotFound()();
} }
bfs::path photo_path = photo_dir_ / book.photo; webcc::fs::path photo_path = photo_dir_ / book.photo;
if (!bfs::exists(photo_path)) { if (!webcc::fs::exists(photo_path)) {
return webcc::ResponseBuilder{}.NotFound()(); return webcc::ResponseBuilder{}.NotFound()();
} }
@ -219,8 +215,8 @@ webcc::ResponsePtr BookPhotoView::Delete(webcc::RequestPtr request) {
} }
// Error handling is simplified. // Error handling is simplified.
boost::system::error_code ec; webcc::fs::error_code ec;
bfs::remove(photo_dir_ / book.photo, ec); webcc::fs::remove(photo_dir_ / book.photo, ec);
return webcc::ResponseBuilder{}.OK()(); return webcc::ResponseBuilder{}.OK()();
} }

@ -1,8 +1,7 @@
#ifndef VIEWS_H_ #ifndef VIEWS_H_
#define VIEWS_H_ #define VIEWS_H_
#include "boost/filesystem/path.hpp" #include "webcc/fs.h"
#include "webcc/view.h" #include "webcc/view.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -25,7 +24,7 @@ private:
// URL: /books/{id} // URL: /books/{id}
class BookDetailView : public webcc::View { class BookDetailView : public webcc::View {
public: public:
explicit BookDetailView(boost::filesystem::path photo_dir); explicit BookDetailView(webcc::fs::path photo_dir);
webcc::ResponsePtr Handle(webcc::RequestPtr request) override; webcc::ResponsePtr Handle(webcc::RequestPtr request) override;
@ -40,7 +39,7 @@ private:
webcc::ResponsePtr Delete(webcc::RequestPtr request); webcc::ResponsePtr Delete(webcc::RequestPtr request);
private: private:
boost::filesystem::path photo_dir_; webcc::fs::path photo_dir_;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -48,7 +47,7 @@ private:
// URL: /books/{id}/photo // URL: /books/{id}/photo
class BookPhotoView : public webcc::View { class BookPhotoView : public webcc::View {
public: public:
explicit BookPhotoView(boost::filesystem::path photo_dir); explicit BookPhotoView(webcc::fs::path photo_dir);
webcc::ResponsePtr Handle(webcc::RequestPtr request) override; webcc::ResponsePtr Handle(webcc::RequestPtr request) override;
@ -68,7 +67,7 @@ private:
webcc::ResponsePtr Delete(webcc::RequestPtr request); webcc::ResponsePtr Delete(webcc::RequestPtr request);
private: private:
boost::filesystem::path photo_dir_; webcc::fs::path photo_dir_;
}; };
#endif // VIEWS_H_ #endif // VIEWS_H_

@ -2,13 +2,10 @@
#include <iostream> #include <iostream>
#include "boost/filesystem/operations.hpp"
#include "webcc/client_session.h" #include "webcc/client_session.h"
#include "webcc/fs.h"
#include "webcc/logger.h" #include "webcc/logger.h"
namespace bfs = boost::filesystem;
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if (argc < 2) { if (argc < 2) {
std::cout << "Usage: form_client <upload_dir> [url]" << std::endl; std::cout << "Usage: form_client <upload_dir> [url]" << std::endl;
@ -29,7 +26,7 @@ int main(int argc, char* argv[]) {
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE); WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
const bfs::path upload_dir(argv[1]); const webcc::fs::path upload_dir(argv[1]);
std::string url; std::string url;
if (argc == 3) { if (argc == 3) {
@ -38,7 +35,7 @@ int main(int argc, char* argv[]) {
url = "http://httpbin.org/post"; url = "http://httpbin.org/post";
} }
if (!bfs::is_directory(upload_dir) || !bfs::exists(upload_dir)) { if (!webcc::fs::is_directory(upload_dir) || !webcc::fs::exists(upload_dir)) {
std::cerr << "Invalid upload dir!" << std::endl; std::cerr << "Invalid upload dir!" << std::endl;
return 1; return 1;
} }

@ -5,8 +5,6 @@
#include "webcc/client_session.h" #include "webcc/client_session.h"
#include "webcc/logger.h" #include "webcc/logger.h"
namespace bfs = boost::filesystem;
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE); WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);

@ -1,7 +1,5 @@
#include "webcc/body.h" #include "webcc/body.h"
#include "boost/filesystem/operations.hpp"
#include "webcc/logger.h" #include "webcc/logger.h"
#include "webcc/utility.h" #include "webcc/utility.h"
@ -9,8 +7,6 @@
#include "webcc/gzip.h" #include "webcc/gzip.h"
#endif #endif
namespace bfs = boost::filesystem;
namespace webcc { namespace webcc {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -157,7 +153,7 @@ void FormBody::Free(std::size_t index) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
FileBody::FileBody(const bfs::path& path, std::size_t chunk_size) FileBody::FileBody(const fs::path& path, std::size_t chunk_size)
: path_(path), chunk_size_(chunk_size), auto_delete_(false), size_(0) { : path_(path), chunk_size_(chunk_size), auto_delete_(false), size_(0) {
size_ = utility::TellSize(path_); size_ = utility::TellSize(path_);
if (size_ == kInvalidLength) { if (size_ == kInvalidLength) {
@ -165,15 +161,15 @@ FileBody::FileBody(const bfs::path& path, std::size_t chunk_size)
} }
} }
FileBody::FileBody(const bfs::path& path, bool auto_delete) FileBody::FileBody(const fs::path& path, bool auto_delete)
: path_(path), chunk_size_(0), auto_delete_(auto_delete), size_(0) { : path_(path), chunk_size_(0), auto_delete_(auto_delete), size_(0) {
// Don't need to tell file size. // Don't need to tell file size.
} }
FileBody::~FileBody() { FileBody::~FileBody() {
if (auto_delete_ && !path_.empty()) { if (auto_delete_ && !path_.empty()) {
boost::system::error_code ec; fs::error_code ec;
bfs::remove(path_, ec); fs::remove(path_, ec);
if (ec) { if (ec) {
LOG_ERRO("Failed to remove file (%s).", ec.message().c_str()); LOG_ERRO("Failed to remove file (%s).", ec.message().c_str());
} }
@ -209,7 +205,7 @@ void FileBody::Dump(std::ostream& os, const std::string& prefix) const {
os << prefix << "<file: " << path_.string() << ">" << std::endl; os << prefix << "<file: " << path_.string() << ">" << std::endl;
} }
bool FileBody::Move(const bfs::path& new_path) { bool FileBody::Move(const fs::path& new_path) {
if (path_ == new_path) { if (path_ == new_path) {
return false; return false;
} }
@ -218,8 +214,8 @@ bool FileBody::Move(const bfs::path& new_path) {
ifstream_.close(); ifstream_.close();
} }
boost::system::error_code ec; fs::error_code ec;
bfs::rename(path_, new_path, ec); fs::rename(path_, new_path, ec);
if (ec) { if (ec) {
LOG_ERRO("Failed to rename file (%s).", ec.message().c_str()); LOG_ERRO("Failed to rename file (%s).", ec.message().c_str());

@ -1,15 +1,12 @@
#ifndef WEBCC_BODY_H_ #ifndef WEBCC_BODY_H_
#define WEBCC_BODY_H_ #define WEBCC_BODY_H_
#include <fstream>
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include "boost/filesystem/fstream.hpp"
#include "boost/filesystem/path.hpp"
#include "webcc/common.h" #include "webcc/common.h"
#include "webcc/fs.h"
namespace webcc { namespace webcc {
@ -154,14 +151,14 @@ private:
class FileBody : public Body { class FileBody : public Body {
public: public:
// For message to be sent out. // For message to be sent out.
FileBody(const boost::filesystem::path& path, std::size_t chunk_size); FileBody(const fs::path& path, std::size_t chunk_size);
// For message received. // For message received.
// No |chunk_size| is needed since you don't iterate the payload of a // No |chunk_size| is needed since you don't iterate the payload of a
// received message. // received message.
// If |auto_delete| is true, the file will be deleted on destructor unless it // If |auto_delete| is true, the file will be deleted on destructor unless it
// is moved to another path (see Move()). // is moved to another path (see Move()).
FileBody(const boost::filesystem::path& path, bool auto_delete = false); FileBody(const fs::path& path, bool auto_delete = false);
~FileBody() override; ~FileBody() override;
@ -175,7 +172,7 @@ public:
void Dump(std::ostream& os, const std::string& prefix) const override; void Dump(std::ostream& os, const std::string& prefix) const override;
const boost::filesystem::path& path() const { const fs::path& path() const {
return path_; return path_;
} }
@ -188,17 +185,17 @@ public:
// If |new_path| resolves to an existing non-directory file, it is removed. // If |new_path| resolves to an existing non-directory file, it is removed.
// If |new_path| resolves to an existing directory, it is removed if empty // If |new_path| resolves to an existing directory, it is removed if empty
// on ISO/IEC 9945 but is an error on Windows. // on ISO/IEC 9945 but is an error on Windows.
// See boost::filesystem::rename() for more details. // See fs::rename() for more details.
bool Move(const boost::filesystem::path& new_path); bool Move(const fs::path& new_path);
private: private:
boost::filesystem::path path_; fs::path path_;
std::size_t chunk_size_; std::size_t chunk_size_;
bool auto_delete_; bool auto_delete_;
std::size_t size_; // File size in bytes std::size_t size_; // File size in bytes
boost::filesystem::ifstream ifstream_; fs::ifstream ifstream_;
std::string chunk_; std::string chunk_;
}; };

@ -8,8 +8,6 @@
#include "webcc/string.h" #include "webcc/string.h"
#include "webcc/utility.h" #include "webcc/utility.h"
namespace bfs = boost::filesystem;
namespace webcc { namespace webcc {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -194,7 +192,7 @@ FormPartPtr FormPart::New(const std::string& name, std::string&& data,
return form_part; return form_part;
} }
FormPartPtr FormPart::NewFile(const std::string& name, const bfs::path& path, FormPartPtr FormPart::NewFile(const std::string& name, const fs::path& path,
const std::string& media_type) { const std::string& media_type) {
auto form_part = std::make_shared<FormPart>(); auto form_part = std::make_shared<FormPart>();

@ -6,8 +6,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "boost/filesystem/path.hpp" #include "webcc/fs.h"
#include "webcc/globals.h" #include "webcc/globals.h"
namespace webcc { namespace webcc {
@ -158,8 +157,7 @@ public:
// Construct a file part. // Construct a file part.
// The file name will be extracted from path. // The file name will be extracted from path.
// The media type, if not provided, will be inferred from file extension. // The media type, if not provided, will be inferred from file extension.
static FormPartPtr NewFile(const std::string& name, static FormPartPtr NewFile(const std::string& name, const fs::path& path,
const boost::filesystem::path& path,
const std::string& media_type = ""); const std::string& media_type = "");
// API: SERVER // API: SERVER
@ -230,7 +228,7 @@ private:
std::string name_; std::string name_;
// The path of the file to post. // The path of the file to post.
boost::filesystem::path path_; fs::path path_;
// The original local file name. // The original local file name.
// E.g., "baby.jpg". // E.g., "baby.jpg".

@ -17,4 +17,7 @@
// Set 1/0 to enable/disable GZIP compression. // Set 1/0 to enable/disable GZIP compression.
#define WEBCC_ENABLE_GZIP 0 #define WEBCC_ENABLE_GZIP 0
// Set 1 to use C++17 filesystem or 0 to use Boost filesystem.
#define WEBCC_USE_STD_FILESYSTEM 1
#endif // WEBCC_CONFIG_H_ #endif // WEBCC_CONFIG_H_

@ -19,4 +19,7 @@
// Set 1/0 to enable/disable GZIP compression. // Set 1/0 to enable/disable GZIP compression.
#define WEBCC_ENABLE_GZIP @WEBCC_ENABLE_GZIP@ #define WEBCC_ENABLE_GZIP @WEBCC_ENABLE_GZIP@
// Set 1 to use C++17 filesystem or 0 to use Boost filesystem.
#define WEBCC_USE_STD_FILESYSTEM @WEBCC_USE_STD_FILESYSTEM@
#endif // WEBCC_CONFIG_H_ #endif // WEBCC_CONFIG_H_

@ -0,0 +1,65 @@
#ifndef WEBCC_FS_H_
#define WEBCC_FS_H_
// Use std or boost filesystem according to config.
#include "webcc/config.h" // for WEBCC_USE_STD_FILESYSTEM
#if WEBCC_USE_STD_FILESYSTEM
#include <filesystem>
#include <fstream>
#else
#include "boost/filesystem/fstream.hpp"
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#endif // WEBCC_USE_STD_FILESYSTEM
namespace webcc {
namespace fs {
#if WEBCC_USE_STD_FILESYSTEM
// types
using std::error_code;
using std::ifstream;
using std::ofstream;
using std::filesystem::path;
using std::filesystem::filesystem_error;
// functions
using std::filesystem::rename;
using std::filesystem::remove;
using std::filesystem::exists;
using std::filesystem::is_directory;
using std::filesystem::is_regular_file;
using std::filesystem::create_directory;
using std::filesystem::create_directories;
using std::filesystem::current_path;
using std::filesystem::temp_directory_path;
#else
// types
using boost::system::error_code;
using boost::filesystem::ifstream;
using boost::filesystem::ofstream;
using boost::filesystem::path;
using boost::filesystem::filesystem_error;
// functions
using boost::filesystem::rename;
using boost::filesystem::remove;
using boost::filesystem::exists;
using boost::filesystem::is_directory;
using boost::filesystem::is_regular_file;
using boost::filesystem::create_directory;
using boost::filesystem::create_directories;
using boost::filesystem::current_path;
using boost::filesystem::temp_directory_path;
#endif // WEBCC_USE_STD_FILESYSTEM
} // namespace fs
} // namespace webcc
#endif // WEBCC_FS_H_

@ -126,6 +126,8 @@ namespace media_types {
const char* const kApplicationJson = "application/json"; const char* const kApplicationJson = "application/json";
const char* const kApplicationSoapXml = "application/soap+xml"; const char* const kApplicationSoapXml = "application/soap+xml";
const char* const kApplicationFormUrlEncoded =
"application/x-www-form-urlencoded";
const char* const kTextPlain = "text/plain"; const char* const kTextPlain = "text/plain";
const char* const kTextXml = "text/xml"; const char* const kTextXml = "text/xml";

@ -18,11 +18,7 @@
// For getting thread ID. // For getting thread ID.
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/types.h> #include <sys/types.h>
#endif #endif // defined(_WIN32) || defined(_WIN64)
#include "boost/filesystem/operations.hpp"
namespace bfs = boost::filesystem;
namespace webcc { namespace webcc {
@ -36,7 +32,7 @@ static const char* kLevelNames[] = {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static FILE* FOpen(const bfs::path& path, bool overwrite) { static FILE* FOpen(const fs::path& path, bool overwrite) {
#if (defined(_WIN32) || defined(_WIN64)) #if (defined(_WIN32) || defined(_WIN64))
return _wfopen(path.wstring().c_str(), overwrite ? L"w+" : L"a+"); return _wfopen(path.wstring().c_str(), overwrite ? L"w+" : L"a+");
#else #else
@ -53,7 +49,7 @@ struct Logger {
} }
} }
void Init(const bfs::path& path, int _modes) { void Init(const fs::path& path, int _modes) {
modes = _modes; modes = _modes;
// Create log file only if necessary. // Create log file only if necessary.
@ -155,14 +151,14 @@ static std::string GetThreadID() {
return thread_id; return thread_id;
} }
static bfs::path InitLogPath(const bfs::path& dir) { static fs::path InitLogPath(const fs::path& dir) {
if (dir.empty()) { if (dir.empty()) {
return bfs::current_path() / WEBCC_LOG_FILE_NAME; return fs::current_path() / WEBCC_LOG_FILE_NAME;
} }
boost::system::error_code ec; fs::error_code ec;
if (!bfs::exists(dir, ec) || !bfs::is_directory(dir, ec)) { if (!fs::exists(dir, ec) || !fs::is_directory(dir, ec)) {
if (!bfs::create_directories(dir, ec) || ec) { if (!fs::create_directories(dir, ec) || ec) {
return {}; return {};
} }
} }
@ -170,7 +166,7 @@ static bfs::path InitLogPath(const bfs::path& dir) {
return (dir / WEBCC_LOG_FILE_NAME); return (dir / WEBCC_LOG_FILE_NAME);
} }
void LogInit(const bfs::path& dir, int modes) { void LogInit(const fs::path& dir, int modes) {
// Suppose this is called from the main thread. // Suppose this is called from the main thread.
g_main_thread_id = DoGetThreadID(); g_main_thread_id = DoGetThreadID();

@ -9,7 +9,7 @@
#include <cstring> // for strrchr() #include <cstring> // for strrchr()
#include <string> #include <string>
#include "boost/filesystem/path.hpp" #include "webcc/fs.h"
// Log levels. // Log levels.
// VERB is similar to DEBUG commonly used by other projects. // VERB is similar to DEBUG commonly used by other projects.
@ -44,7 +44,7 @@ const int LOG_FILE_OVERWRITE = LOG_FILE | LOG_OVERWRITE;
// Initialize logger. // Initialize logger.
// If |dir| is empty, log file will be generated in current directory. // If |dir| is empty, log file will be generated in current directory.
void LogInit(const boost::filesystem::path& dir, int modes); void LogInit(const fs::path& dir, int modes);
void Log(int level, const char* file, int line, const char* format, ...); void Log(int level, const char* file, int line, const char* format, ...);

@ -1,7 +1,6 @@
#include "webcc/parser.h" #include "webcc/parser.h"
#include "boost/algorithm/string.hpp" #include "boost/algorithm/string.hpp"
#include "boost/filesystem/operations.hpp"
#include "webcc/logger.h" #include "webcc/logger.h"
#include "webcc/message.h" #include "webcc/message.h"
@ -12,8 +11,6 @@
#include "webcc/gzip.h" #include "webcc/gzip.h"
#endif #endif
namespace bfs = boost::filesystem;
namespace webcc { namespace webcc {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -70,7 +67,7 @@ bool StringBodyHandler::Finish() {
bool FileBodyHandler::OpenFile() { bool FileBodyHandler::OpenFile() {
try { try {
temp_path_ = bfs::temp_directory_path(); temp_path_ = fs::temp_directory_path();
// Generate a random string as file name. // Generate a random string as file name.
// A replacement of boost::filesystem::unique_path(). // A replacement of boost::filesystem::unique_path().
@ -79,7 +76,7 @@ bool FileBodyHandler::OpenFile() {
LOG_VERB("Generate a temp path for streaming: %s", LOG_VERB("Generate a temp path for streaming: %s",
temp_path_.string().c_str()); temp_path_.string().c_str());
} catch (const bfs::filesystem_error&) { } catch (const fs::filesystem_error&) {
LOG_ERRO("Failed to generate temp path for streaming"); LOG_ERRO("Failed to generate temp path for streaming");
return false; return false;
} }

@ -4,10 +4,8 @@
#include <fstream> #include <fstream>
#include <string> #include <string>
#include "boost/filesystem/fstream.hpp"
#include "boost/filesystem/path.hpp"
#include "webcc/common.h" #include "webcc/common.h"
#include "webcc/fs.h"
#include "webcc/globals.h" #include "webcc/globals.h"
namespace webcc { namespace webcc {
@ -84,8 +82,8 @@ public:
private: private:
std::size_t streamed_size_ = 0; std::size_t streamed_size_ = 0;
boost::filesystem::ofstream ofstream_; fs::ofstream ofstream_;
boost::filesystem::path temp_path_; fs::path temp_path_;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

@ -9,8 +9,6 @@
#include "webcc/gzip.h" #include "webcc/gzip.h"
#endif #endif
namespace bfs = boost::filesystem;
namespace webcc { namespace webcc {
RequestPtr RequestBuilder::operator()() { RequestPtr RequestBuilder::operator()() {
@ -67,7 +65,7 @@ RequestBuilder& RequestBuilder::AcceptGzip(bool gzip) {
#endif // WEBCC_ENABLE_GZIP #endif // WEBCC_ENABLE_GZIP
RequestBuilder& RequestBuilder::File(const bfs::path& path, RequestBuilder& RequestBuilder::File(const fs::path& path,
bool infer_media_type, bool infer_media_type,
std::size_t chunk_size) { std::size_t chunk_size) {
body_.reset(new FileBody{ path, chunk_size }); body_.reset(new FileBody{ path, chunk_size });
@ -80,7 +78,7 @@ RequestBuilder& RequestBuilder::File(const bfs::path& path,
} }
RequestBuilder& RequestBuilder::FormFile(const std::string& name, RequestBuilder& RequestBuilder::FormFile(const std::string& name,
const bfs::path& path, const fs::path& path,
const std::string& media_type) { const std::string& media_type) {
assert(!name.empty()); assert(!name.empty());
return Form(FormPart::NewFile(name, path, media_type)); return Form(FormPart::NewFile(name, path, media_type));

@ -4,26 +4,29 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "boost/filesystem/path.hpp" #include "webcc/fs.h"
#include "webcc/request.h" #include "webcc/request.h"
#include "webcc/url.h" #include "webcc/url.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Handy macros for creating a RequestBuilder. // Handy macros for creating a RequestBuilder.
#define WEBCC_GET(url) webcc::RequestBuilder{}.Get(url, false) #define WEBCC_RB webcc::RequestBuilder{}
#define WEBCC_GET_ENC(url) webcc::RequestBuilder{}.Get(url, true)
#define WEBCC_HEAD(url) webcc::RequestBuilder{}.Head(url, false) // clang-format off
#define WEBCC_HEAD_ENC(url) webcc::RequestBuilder{}.Head(url, true) #define WEBCC_GET(url) WEBCC_RB.Get(url, false)
#define WEBCC_POST(url) webcc::RequestBuilder{}.Post(url, false) #define WEBCC_GET_ENC(url) WEBCC_RB.Get(url, true)
#define WEBCC_POST_ENC(url) webcc::RequestBuilder{}.Post(url, true) #define WEBCC_HEAD(url) WEBCC_RB.Head(url, false)
#define WEBCC_PUT(url) webcc::RequestBuilder{}.Put(url, false) #define WEBCC_HEAD_ENC(url) WEBCC_RB.Head(url, true)
#define WEBCC_PUT_ENC(url) webcc::RequestBuilder{}.Put(url, true) #define WEBCC_POST(url) WEBCC_RB.Post(url, false)
#define WEBCC_DELETE(url) webcc::RequestBuilder{}.Delete(url, false) #define WEBCC_POST_ENC(url) WEBCC_RB.Post(url, true)
#define WEBCC_DELETE_ENC(url) webcc::RequestBuilder{}.Delete(url, true) #define WEBCC_PUT(url) WEBCC_RB.Put(url, false)
#define WEBCC_PATCH(url) webcc::RequestBuilder{}.Patch(url, false) #define WEBCC_PUT_ENC(url) WEBCC_RB.Put(url, true)
#define WEBCC_PATCH_ENC(url) webcc::RequestBuilder{}.Patch(url, true) #define WEBCC_DELETE(url) WEBCC_RB.Delete(url, false)
#define WEBCC_DELETE_ENC(url) WEBCC_RB.Delete(url, true)
#define WEBCC_PATCH(url) WEBCC_RB.Patch(url, false)
#define WEBCC_PATCH_ENC(url) WEBCC_RB.Patch(url, true)
// clang-format on
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -143,8 +146,7 @@ public:
// Use the file content as body. // Use the file content as body.
// NOTE: Error::kFileError might be thrown. // NOTE: Error::kFileError might be thrown.
RequestBuilder& File(const boost::filesystem::path& path, RequestBuilder& File(const fs::path& path, bool infer_media_type = true,
bool infer_media_type = true,
std::size_t chunk_size = 1024); std::size_t chunk_size = 1024);
// Add a form part. // Add a form part.
@ -154,8 +156,7 @@ public:
} }
// Add a form part of file. // Add a form part of file.
RequestBuilder& FormFile(const std::string& name, RequestBuilder& FormFile(const std::string& name, const fs::path& path,
const boost::filesystem::path& path,
const std::string& media_type = ""); const std::string& media_type = "");
// Add a form part of string data. // Add a form part of string data.

@ -8,8 +8,6 @@
#include "webcc/gzip.h" #include "webcc/gzip.h"
#endif #endif
namespace bfs = boost::filesystem;
namespace webcc { namespace webcc {
ResponsePtr ResponseBuilder::operator()() { ResponsePtr ResponseBuilder::operator()() {
@ -45,7 +43,7 @@ ResponsePtr ResponseBuilder::operator()() {
return response; return response;
} }
ResponseBuilder& ResponseBuilder::File(const bfs::path& path, ResponseBuilder& ResponseBuilder::File(const fs::path& path,
bool infer_media_type, bool infer_media_type,
std::size_t chunk_size) { std::size_t chunk_size) {
body_.reset(new FileBody{ path, chunk_size }); body_.reset(new FileBody{ path, chunk_size });

@ -4,8 +4,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "boost/filesystem/path.hpp" #include "webcc/fs.h"
#include "webcc/request.h" #include "webcc/request.h"
#include "webcc/response.h" #include "webcc/response.h"
@ -96,8 +95,7 @@ public:
// Use the file content as body. // Use the file content as body.
// NOTE: Error::kFileError might be thrown. // NOTE: Error::kFileError might be thrown.
ResponseBuilder& File(const boost::filesystem::path& path, ResponseBuilder& File(const fs::path& path, bool infer_media_type = true,
bool infer_media_type = true,
std::size_t chunk_size = 1024); std::size_t chunk_size = 1024);
ResponseBuilder& Header(const std::string& key, const std::string& value) { ResponseBuilder& Header(const std::string& key, const std::string& value) {

@ -9,16 +9,16 @@ namespace webcc {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
namespace { // Split HTTP response status line to three parts.
// Don't use the general split function because the reason part might also
void SplitStartLine(const std::string& line, std::vector<std::string>* parts) { // contain spaces.
const char SPACE = ' '; static void SplitStatusLine(const std::string& line,
std::vector<std::string>* parts) {
std::size_t off = 0; std::size_t off = 0;
std::size_t pos = 0; std::size_t pos = 0;
for (std::size_t i = 0; i < 2; ++i) { for (std::size_t i = 0; i < 2; ++i) {
pos = line.find(SPACE, off); pos = line.find(' ', off);
if (pos == std::string::npos) { if (pos == std::string::npos) {
break; break;
} }
@ -26,7 +26,9 @@ void SplitStartLine(const std::string& line, std::vector<std::string>* parts) {
parts->push_back(line.substr(off, pos - off)); parts->push_back(line.substr(off, pos - off));
off = pos + 1; off = pos + 1;
for (; off < line.size() && line[off] == SPACE; ++off) { // Skip spaces
while (off < line.size() && line[off] == ' ') {
++off;
} }
} }
@ -35,8 +37,6 @@ void SplitStartLine(const std::string& line, std::vector<std::string>* parts) {
} }
} }
} // namespace
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ResponseParser::Init(Response* response, bool stream) { void ResponseParser::Init(Response* response, bool stream) {
@ -48,7 +48,7 @@ void ResponseParser::Init(Response* response, bool stream) {
bool ResponseParser::ParseStartLine(const std::string& line) { bool ResponseParser::ParseStartLine(const std::string& line) {
std::vector<std::string> parts; std::vector<std::string> parts;
SplitStartLine(line, &parts); SplitStatusLine(line, &parts);
if (parts.size() < 2) { if (parts.size() < 2) {
LOG_ERRO("Invalid HTTP response status line: %s", line.c_str()); LOG_ERRO("Invalid HTTP response status line: %s", line.c_str());

@ -4,22 +4,18 @@
#include <fstream> #include <fstream>
#include <utility> #include <utility>
#include "boost/filesystem/operations.hpp"
#include "webcc/body.h" #include "webcc/body.h"
#include "webcc/logger.h" #include "webcc/logger.h"
#include "webcc/request.h" #include "webcc/request.h"
#include "webcc/response.h" #include "webcc/response.h"
#include "webcc/utility.h" #include "webcc/utility.h"
namespace bfs = boost::filesystem;
using tcp = boost::asio::ip::tcp; using tcp = boost::asio::ip::tcp;
namespace webcc { namespace webcc {
Server::Server(boost::asio::ip::tcp protocol, std::uint16_t port, Server::Server(boost::asio::ip::tcp protocol, std::uint16_t port,
const bfs::path& doc_root) const fs::path& doc_root)
: protocol_(protocol), : protocol_(protocol),
port_(port), port_(port),
doc_root_(doc_root), doc_root_(doc_root),
@ -304,10 +300,10 @@ bool Server::MatchViewOrStatic(const std::string& method,
// Try to match a static file. // Try to match a static file.
if (method == methods::kGet && !doc_root_.empty()) { if (method == methods::kGet && !doc_root_.empty()) {
bfs::path path = doc_root_ / url; fs::path path = doc_root_ / url;
boost::system::error_code ec; fs::error_code ec;
if (!bfs::is_directory(path, ec) && bfs::exists(path, ec)) { if (!fs::is_directory(path, ec) && fs::exists(path, ec)) {
return true; return true;
} }
} }
@ -323,7 +319,7 @@ ResponsePtr Server::ServeStatic(RequestPtr request) {
return {}; return {};
} }
bfs::path path = doc_root_ / request->url().path(); fs::path path = doc_root_ / request->url().path();
try { try {
// NOTE: FileBody might throw Error::kFileError. // NOTE: FileBody might throw Error::kFileError.

@ -5,14 +5,13 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "boost/filesystem/path.hpp"
#include "boost/asio/io_context.hpp" #include "boost/asio/io_context.hpp"
#include "boost/asio/ip/tcp.hpp" #include "boost/asio/ip/tcp.hpp"
#include "boost/asio/signal_set.hpp" #include "boost/asio/signal_set.hpp"
#include "webcc/connection.h" #include "webcc/connection.h"
#include "webcc/connection_pool.h" #include "webcc/connection_pool.h"
#include "webcc/fs.h"
#include "webcc/queue.h" #include "webcc/queue.h"
#include "webcc/router.h" #include "webcc/router.h"
#include "webcc/url.h" #include "webcc/url.h"
@ -22,7 +21,7 @@ namespace webcc {
class Server : public Router { class Server : public Router {
public: public:
Server(boost::asio::ip::tcp protocol, std::uint16_t port, Server(boost::asio::ip::tcp protocol, std::uint16_t port,
const boost::filesystem::path& doc_root = {}); const fs::path& doc_root = {});
Server(const Server&) = delete; Server(const Server&) = delete;
Server& operator=(const Server&) = delete; Server& operator=(const Server&) = delete;
@ -108,7 +107,7 @@ private:
std::uint16_t port_ = 0; std::uint16_t port_ = 0;
// The directory with the static files to be served. // The directory with the static files to be served.
boost::filesystem::path doc_root_; fs::path doc_root_;
// The size of the buffer for reading request. // The size of the buffer for reading request.
std::size_t buffer_size_ = kBufferSize; std::size_t buffer_size_ = kBufferSize;

@ -7,13 +7,9 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "boost/filesystem/fstream.hpp"
#include "webcc/string.h" #include "webcc/string.h"
#include "webcc/version.h" #include "webcc/version.h"
namespace bfs = boost::filesystem;
namespace webcc { namespace webcc {
namespace utility { namespace utility {
@ -32,18 +28,18 @@ std::string HttpDate() {
return date.str(); return date.str();
} }
std::size_t TellSize(const bfs::path& path) { std::size_t TellSize(const fs::path& path) {
// Flag "ate": seek to the end of stream immediately after open. // Flag "ate": seek to the end of stream immediately after open.
bfs::ifstream stream{ path, std::ios::binary | std::ios::ate }; fs::ifstream stream{ path, std::ios::binary | std::ios::ate };
if (stream.fail()) { if (stream.fail()) {
return kInvalidLength; return kInvalidLength;
} }
return static_cast<std::size_t>(stream.tellg()); return static_cast<std::size_t>(stream.tellg());
} }
bool ReadFile(const bfs::path& path, std::string* output) { bool ReadFile(const fs::path& path, std::string* output) {
// Flag "ate": seek to the end of stream immediately after open. // Flag "ate": seek to the end of stream immediately after open.
bfs::ifstream stream{ path, std::ios::binary | std::ios::ate }; fs::ifstream stream{ path, std::ios::binary | std::ios::ate };
if (stream.fail()) { if (stream.fail()) {
return false; return false;
} }

@ -5,8 +5,8 @@
#include <string> #include <string>
#include "boost/asio/ip/tcp.hpp" #include "boost/asio/ip/tcp.hpp"
#include "boost/filesystem/path.hpp"
#include "webcc/fs.h"
#include "webcc/globals.h" #include "webcc/globals.h"
namespace webcc { namespace webcc {
@ -22,10 +22,10 @@ std::string HttpDate();
// Tell the size in bytes of the given file. // Tell the size in bytes of the given file.
// Return kInvalidLength (-1) on failure. // Return kInvalidLength (-1) on failure.
std::size_t TellSize(const boost::filesystem::path& path); std::size_t TellSize(const fs::path& path);
// Read entire file into string. // Read entire file into string.
bool ReadFile(const boost::filesystem::path& path, std::string* output); bool ReadFile(const fs::path& path, std::string* output);
// Dump the string data line by line to achieve more readability. // Dump the string data line by line to achieve more readability.
// Also limit the maximum size of the data to be dumped. // Also limit the maximum size of the data to be dumped.

Loading…
Cancel
Save