switch back to boost::filesystem to avoid the requirement of c++17

This commit is contained in:
Chunting Gu
2020-09-07 19:01:31 +08:00
parent e7f88da2b2
commit 84476f75f7
31 changed files with 175 additions and 192 deletions
+11 -7
View File
@@ -1,5 +1,7 @@
#include "webcc/body.h"
#include "boost/filesystem/operations.hpp"
#include "webcc/logger.h"
#include "webcc/utility.h"
@@ -7,6 +9,8 @@
#include "webcc/gzip.h"
#endif
namespace bfs = boost::filesystem;
namespace webcc {
// -----------------------------------------------------------------------------
@@ -153,7 +157,7 @@ void FormBody::Free(std::size_t index) {
// -----------------------------------------------------------------------------
FileBody::FileBody(const std::filesystem::path& path, std::size_t chunk_size)
FileBody::FileBody(const bfs::path& path, std::size_t chunk_size)
: path_(path), chunk_size_(chunk_size), auto_delete_(false), size_(0) {
size_ = utility::TellSize(path_);
if (size_ == kInvalidLength) {
@@ -161,15 +165,15 @@ FileBody::FileBody(const std::filesystem::path& path, std::size_t chunk_size)
}
}
FileBody::FileBody(const std::filesystem::path& path, bool auto_delete)
FileBody::FileBody(const bfs::path& path, bool auto_delete)
: path_(path), chunk_size_(0), auto_delete_(auto_delete), size_(0) {
// Don't need to tell file size.
}
FileBody::~FileBody() {
if (auto_delete_ && !path_.empty()) {
std::error_code ec;
std::filesystem::remove(path_, ec);
boost::system::error_code ec;
bfs::remove(path_, ec);
if (ec) {
LOG_ERRO("Failed to remove file (%s).", ec.message().c_str());
}
@@ -205,7 +209,7 @@ void FileBody::Dump(std::ostream& os, const std::string& prefix) const {
os << prefix << "<file: " << path_.string() << ">" << std::endl;
}
bool FileBody::Move(const std::filesystem::path& new_path) {
bool FileBody::Move(const bfs::path& new_path) {
if (path_ == new_path) {
return false;
}
@@ -214,8 +218,8 @@ bool FileBody::Move(const std::filesystem::path& new_path) {
ifstream_.close();
}
std::error_code ec;
std::filesystem::rename(path_, new_path, ec);
boost::system::error_code ec;
bfs::rename(path_, new_path, ec);
if (ec) {
LOG_ERRO("Failed to rename file (%s).", ec.message().c_str());
+10 -8
View File
@@ -1,12 +1,14 @@
#ifndef WEBCC_BODY_H_
#define WEBCC_BODY_H_
#include <filesystem>
#include <fstream>
#include <memory>
#include <string>
#include <utility>
#include "boost/filesystem/fstream.hpp"
#include "boost/filesystem/path.hpp"
#include "webcc/common.h"
namespace webcc {
@@ -152,14 +154,14 @@ private:
class FileBody : public Body {
public:
// For message to be sent out.
FileBody(const std::filesystem::path& path, std::size_t chunk_size);
FileBody(const boost::filesystem::path& path, std::size_t chunk_size);
// For message received.
// No |chunk_size| is needed since you don't iterate the payload of a
// received message.
// If |auto_delete| is true, the file will be deleted on destructor unless it
// is moved to another path (see Move()).
FileBody(const std::filesystem::path& path, bool auto_delete = false);
FileBody(const boost::filesystem::path& path, bool auto_delete = false);
~FileBody() override;
@@ -173,7 +175,7 @@ public:
void Dump(std::ostream& os, const std::string& prefix) const override;
const std::filesystem::path& path() const {
const boost::filesystem::path& path() const {
return path_;
}
@@ -186,17 +188,17 @@ public:
// 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
// on ISO/IEC 9945 but is an error on Windows.
// See std::filesystem::rename() for more details.
bool Move(const std::filesystem::path& new_path);
// See boost::filesystem::rename() for more details.
bool Move(const boost::filesystem::path& new_path);
private:
std::filesystem::path path_;
boost::filesystem::path path_;
std::size_t chunk_size_;
bool auto_delete_;
std::size_t size_; // File size in bytes
std::ifstream ifstream_;
boost::filesystem::ifstream ifstream_;
std::string chunk_;
};
+3 -2
View File
@@ -6,6 +6,8 @@
#include "webcc/string.h"
#include "webcc/utility.h"
namespace bfs = boost::filesystem;
namespace webcc {
// -----------------------------------------------------------------------------
@@ -190,8 +192,7 @@ FormPartPtr FormPart::New(const std::string& name, std::string&& data,
return form_part;
}
FormPartPtr FormPart::NewFile(const std::string& name,
const std::filesystem::path& path,
FormPartPtr FormPart::NewFile(const std::string& name, const bfs::path& path,
const std::string& media_type) {
auto form_part = std::make_shared<FormPart>();
+4 -3
View File
@@ -2,11 +2,12 @@
#define WEBCC_COMMON_H_
#include <cassert>
#include <filesystem>
#include <string>
#include <utility>
#include <vector>
#include "boost/filesystem/path.hpp"
#include "webcc/globals.h"
namespace webcc {
@@ -158,7 +159,7 @@ public:
// The file name will be extracted from path.
// The media type, if not provided, will be inferred from file extension.
static FormPartPtr NewFile(const std::string& name,
const std::filesystem::path& path,
const boost::filesystem::path& path,
const std::string& media_type = "");
// API: SERVER
@@ -229,7 +230,7 @@ private:
std::string name_;
// The path of the file to post.
std::filesystem::path path_;
boost::filesystem::path path_;
// The original local file name.
// E.g., "baby.jpg".
+13 -10
View File
@@ -6,7 +6,6 @@
#include <chrono>
#include <cstdarg>
#include <ctime>
#include <filesystem>
#include <iomanip> // for put_time
#include <mutex>
#include <sstream>
@@ -21,6 +20,10 @@
#include <sys/types.h>
#endif
#include "boost/filesystem/operations.hpp"
namespace bfs = boost::filesystem;
namespace webcc {
// -----------------------------------------------------------------------------
@@ -33,7 +36,7 @@ static const char* kLevelNames[] = {
// -----------------------------------------------------------------------------
static FILE* FOpen(const std::filesystem::path& path, bool overwrite) {
static FILE* FOpen(const bfs::path& path, bool overwrite) {
#if (defined(_WIN32) || defined(_WIN64))
return _wfopen(path.wstring().c_str(), overwrite ? L"w+" : L"a+");
#else
@@ -45,7 +48,7 @@ struct Logger {
Logger() : file(nullptr), modes(0) {
}
void Init(const std::filesystem::path& path, int _modes) {
void Init(const bfs::path& path, int _modes) {
modes = _modes;
// Create log file only if necessary.
@@ -153,22 +156,22 @@ static std::string GetThreadID() {
return thread_id;
}
static std::filesystem::path InitLogPath(const std::filesystem::path& dir) {
static bfs::path InitLogPath(const bfs::path& dir) {
if (dir.empty()) {
return std::filesystem::current_path() / WEBCC_LOG_FILE_NAME;
return bfs::current_path() / WEBCC_LOG_FILE_NAME;
}
if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) {
std::error_code ec;
if (!std::filesystem::create_directories(dir, ec) || ec) {
return std::filesystem::path{};
if (!bfs::exists(dir) || !bfs::is_directory(dir)) {
boost::system::error_code ec;
if (!bfs::create_directories(dir, ec) || ec) {
return bfs::path{};
}
}
return (dir / WEBCC_LOG_FILE_NAME);
}
void LogInit(const std::filesystem::path& dir, int modes) {
void LogInit(const bfs::path& dir, int modes) {
// Suppose this is called from the main thread.
g_main_thread_id = DoGetThreadID();
+2 -7
View File
@@ -9,12 +9,7 @@
#include <cstring> // for strrchr()
#include <string>
// Avoid include <filesystem> in the header.
namespace std {
namespace filesystem {
class path;
} // namespace filesystem
} // namespace std
#include "boost/filesystem/path.hpp"
// Log levels.
// VERB is similar to DEBUG commonly used by other projects.
@@ -49,7 +44,7 @@ const int LOG_FILE_OVERWRITE = LOG_FILE | LOG_OVERWRITE;
// Initialize logger.
// If |dir| is empty, log file will be generated in current directory.
void LogInit(const std::filesystem::path& dir, int modes);
void LogInit(const boost::filesystem::path& dir, int modes);
void Log(int level, const char* file, int line, const char* format, ...);
+6 -2
View File
@@ -1,5 +1,7 @@
#include "webcc/parser.h"
#include "boost/filesystem/operations.hpp"
#include "webcc/logger.h"
#include "webcc/message.h"
#include "webcc/string.h"
@@ -9,6 +11,8 @@
#include "webcc/gzip.h"
#endif
namespace bfs = boost::filesystem;
namespace webcc {
// -----------------------------------------------------------------------------
@@ -65,7 +69,7 @@ bool StringBodyHandler::Finish() {
bool FileBodyHandler::OpenFile() {
try {
temp_path_ = std::filesystem::temp_directory_path();
temp_path_ = bfs::temp_directory_path();
// Generate a random string as file name.
// A replacement of boost::filesystem::unique_path().
@@ -74,7 +78,7 @@ bool FileBodyHandler::OpenFile() {
LOG_VERB("Generate a temp path for streaming: %s",
temp_path_.string().c_str());
} catch (const std::filesystem::filesystem_error&) {
} catch (const bfs::filesystem_error&) {
LOG_ERRO("Failed to generate temp path for streaming.");
return false;
}
+5 -3
View File
@@ -1,10 +1,12 @@
#ifndef WEBCC_PARSER_H_
#define WEBCC_PARSER_H_
#include <filesystem>
#include <fstream>
#include <string>
#include "boost/filesystem/fstream.hpp"
#include "boost/filesystem/path.hpp"
#include "webcc/common.h"
#include "webcc/globals.h"
@@ -82,8 +84,8 @@ public:
private:
std::size_t streamed_size_ = 0;
std::ofstream ofstream_;
std::filesystem::path temp_path_;
boost::filesystem::ofstream ofstream_;
boost::filesystem::path temp_path_;
};
// -----------------------------------------------------------------------------
+4 -2
View File
@@ -9,6 +9,8 @@
#include "webcc/gzip.h"
#endif
namespace bfs = boost::filesystem;
namespace webcc {
RequestPtr RequestBuilder::operator()() {
@@ -52,7 +54,7 @@ RequestPtr RequestBuilder::operator()() {
return request;
}
RequestBuilder& RequestBuilder::File(const std::filesystem::path& path,
RequestBuilder& RequestBuilder::File(const bfs::path& path,
bool infer_media_type,
std::size_t chunk_size) {
body_.reset(new FileBody{ path, chunk_size });
@@ -65,7 +67,7 @@ RequestBuilder& RequestBuilder::File(const std::filesystem::path& path,
}
RequestBuilder& RequestBuilder::FormFile(const std::string& name,
const std::filesystem::path& path,
const bfs::path& path,
const std::string& media_type) {
assert(!name.empty());
return Form(FormPart::NewFile(name, path, media_type));
+4 -3
View File
@@ -1,10 +1,11 @@
#ifndef WEBCC_REQUEST_BUILDER_H_
#define WEBCC_REQUEST_BUILDER_H_
#include <filesystem>
#include <string>
#include <vector>
#include "boost/filesystem/path.hpp"
#include "webcc/request.h"
#include "webcc/url.h"
@@ -135,7 +136,7 @@ public:
// Use the file content as body.
// NOTE: Error::kFileError might be thrown.
RequestBuilder& File(const std::filesystem::path& path,
RequestBuilder& File(const boost::filesystem::path& path,
bool infer_media_type = true,
std::size_t chunk_size = 1024);
@@ -147,7 +148,7 @@ public:
// Add a form part of file.
RequestBuilder& FormFile(const std::string& name,
const std::filesystem::path& path,
const boost::filesystem::path& path,
const std::string& media_type = "");
// Add a form part of string data.
+3 -1
View File
@@ -8,6 +8,8 @@
#include "webcc/gzip.h"
#endif
namespace bfs = boost::filesystem;
namespace webcc {
ResponsePtr ResponseBuilder::operator()() {
@@ -43,7 +45,7 @@ ResponsePtr ResponseBuilder::operator()() {
return response;
}
ResponseBuilder& ResponseBuilder::File(const std::filesystem::path& path,
ResponseBuilder& ResponseBuilder::File(const bfs::path& path,
bool infer_media_type,
std::size_t chunk_size) {
body_.reset(new FileBody{ path, chunk_size });
+3 -1
View File
@@ -4,6 +4,8 @@
#include <string>
#include <vector>
#include "boost/filesystem/path.hpp"
#include "webcc/request.h"
#include "webcc/response.h"
@@ -94,7 +96,7 @@ public:
// Use the file content as body.
// NOTE: Error::kFileError might be thrown.
ResponseBuilder& File(const std::filesystem::path& path,
ResponseBuilder& File(const boost::filesystem::path& path,
bool infer_media_type = true,
std::size_t chunk_size = 1024);
+7 -5
View File
@@ -4,20 +4,22 @@
#include <fstream>
#include <utility>
#include "boost/filesystem/operations.hpp"
#include "webcc/body.h"
#include "webcc/logger.h"
#include "webcc/request.h"
#include "webcc/response.h"
#include "webcc/utility.h"
namespace sfs = std::filesystem;
namespace bfs = boost::filesystem;
using tcp = boost::asio::ip::tcp;
namespace webcc {
Server::Server(boost::asio::ip::tcp protocol, std::uint16_t port,
const sfs::path& doc_root)
const bfs::path& doc_root)
: protocol_(protocol),
port_(port),
doc_root_(doc_root),
@@ -302,8 +304,8 @@ bool Server::MatchViewOrStatic(const std::string& method,
// Try to match a static file.
if (method == methods::kGet && !doc_root_.empty()) {
sfs::path path = doc_root_ / url;
if (!sfs::is_directory(path) && sfs::exists(path)) {
bfs::path path = doc_root_ / url;
if (!bfs::is_directory(path) && bfs::exists(path)) {
return true;
}
}
@@ -319,7 +321,7 @@ ResponsePtr Server::ServeStatic(RequestPtr request) {
return {};
}
sfs::path path = doc_root_ / request->url().path();
bfs::path path = doc_root_ / request->url().path();
try {
// NOTE: FileBody might throw Error::kFileError.
+4 -3
View File
@@ -1,11 +1,12 @@
#ifndef WEBCC_SERVER_H_
#define WEBCC_SERVER_H_
#include <filesystem>
#include <string>
#include <thread>
#include <vector>
#include "boost/filesystem/path.hpp"
#include "boost/asio/io_context.hpp"
#include "boost/asio/ip/tcp.hpp"
#include "boost/asio/signal_set.hpp"
@@ -21,7 +22,7 @@ namespace webcc {
class Server : public Router {
public:
Server(boost::asio::ip::tcp protocol, std::uint16_t port,
const std::filesystem::path& doc_root = {});
const boost::filesystem::path& doc_root = {});
~Server() = default;
@@ -101,7 +102,7 @@ private:
std::uint16_t port_;
// The directory with the static files to be served.
std::filesystem::path doc_root_;
boost::filesystem::path doc_root_;
// The size of the chunk loaded into memory each time when serving a
// static file.
+8 -5
View File
@@ -2,15 +2,18 @@
#include <algorithm>
#include <ctime>
#include <filesystem>
#include <fstream>
#include <iomanip> // for put_time
#include <iostream>
#include <sstream>
#include "boost/filesystem/fstream.hpp"
#include "webcc/string.h"
#include "webcc/version.h"
namespace bfs = boost::filesystem;
namespace webcc {
namespace utility {
@@ -49,18 +52,18 @@ std::string HttpDate() {
return std::string(buf) + " GMT";
}
std::size_t TellSize(const std::filesystem::path& path) {
std::size_t TellSize(const bfs::path& path) {
// Flag "ate": seek to the end of stream immediately after open.
std::ifstream stream{ path, std::ios::binary | std::ios::ate };
bfs::ifstream stream{ path, std::ios::binary | std::ios::ate };
if (stream.fail()) {
return kInvalidLength;
}
return static_cast<std::size_t>(stream.tellg());
}
bool ReadFile(const std::filesystem::path& path, std::string* output) {
bool ReadFile(const bfs::path& path, std::string* output) {
// Flag "ate": seek to the end of stream immediately after open.
std::ifstream stream{ path, std::ios::binary | std::ios::ate };
bfs::ifstream stream{ path, std::ios::binary | std::ios::ate };
if (stream.fail()) {
return false;
}
+3 -9
View File
@@ -5,16 +5,10 @@
#include <string>
#include "boost/asio/ip/tcp.hpp"
#include "boost/filesystem/path.hpp"
#include "webcc/globals.h"
// Avoid include <filesystem> in the header.
namespace std {
namespace filesystem {
class path;
} // namespace filesystem
} // namespace std
namespace webcc {
namespace utility {
@@ -28,10 +22,10 @@ std::string HttpDate();
// Tell the size in bytes of the given file.
// Return kInvalidLength (-1) on failure.
std::size_t TellSize(const std::filesystem::path& path);
std::size_t TellSize(const boost::filesystem::path& path);
// Read entire file into string.
bool ReadFile(const std::filesystem::path& path, std::string* output);
bool ReadFile(const boost::filesystem::path& path, std::string* output);
// Dump the string data line by line to achieve more readability.
// Also limit the maximum size of the data to be dumped.