replace boost filesystem with std filesystem; upgrade gtest and find it using cmake.
This commit is contained in:
+9
-17
@@ -1,8 +1,6 @@
|
||||
#include "webcc/body.h"
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
#include "boost/core/ignore_unused.hpp"
|
||||
#include "boost/filesystem/operations.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
#include "webcc/utility.h"
|
||||
@@ -11,8 +9,6 @@
|
||||
#include "webcc/gzip.h"
|
||||
#endif
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
namespace webcc {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -61,9 +57,7 @@ void StringBody::InitPayload() {
|
||||
index_ = 0;
|
||||
}
|
||||
|
||||
Payload StringBody::NextPayload(bool free_previous) {
|
||||
boost::ignore_unused(free_previous);
|
||||
|
||||
Payload StringBody::NextPayload(bool /*free_previous*/) {
|
||||
if (index_ == 0) {
|
||||
index_ = 1;
|
||||
return { boost::asio::buffer(data_) };
|
||||
@@ -161,7 +155,7 @@ void FormBody::Free(std::size_t index) {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
FileBody::FileBody(const Path& path, std::size_t chunk_size)
|
||||
FileBody::FileBody(const std::filesystem::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) {
|
||||
@@ -169,15 +163,15 @@ FileBody::FileBody(const Path& path, std::size_t chunk_size)
|
||||
}
|
||||
}
|
||||
|
||||
FileBody::FileBody(const Path& path, bool auto_delete)
|
||||
FileBody::FileBody(const std::filesystem::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()) {
|
||||
boost::system::error_code ec;
|
||||
bfs::remove(path_, ec);
|
||||
std::error_code ec;
|
||||
std::filesystem::remove(path_, ec);
|
||||
if (ec) {
|
||||
LOG_ERRO("Failed to remove file (%s).", ec.message().c_str());
|
||||
}
|
||||
@@ -200,9 +194,7 @@ void FileBody::InitPayload() {
|
||||
}
|
||||
}
|
||||
|
||||
Payload FileBody::NextPayload(bool free_previous) {
|
||||
boost::ignore_unused(free_previous);
|
||||
|
||||
Payload FileBody::NextPayload(bool /*free_previous*/) {
|
||||
if (ifstream_.read(&chunk_[0], chunk_.size()).gcount() > 0) {
|
||||
return {
|
||||
boost::asio::buffer(chunk_.data(), (std::size_t)ifstream_.gcount())
|
||||
@@ -215,7 +207,7 @@ void FileBody::Dump(std::ostream& os, const std::string& prefix) const {
|
||||
os << prefix << "<file: " << path_.string() << ">" << std::endl;
|
||||
}
|
||||
|
||||
bool FileBody::Move(const Path& new_path) {
|
||||
bool FileBody::Move(const std::filesystem::path& new_path) {
|
||||
if (path_ == new_path) {
|
||||
return false;
|
||||
}
|
||||
@@ -224,8 +216,8 @@ bool FileBody::Move(const Path& new_path) {
|
||||
ifstream_.close();
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
bfs::rename(path_, new_path, ec);
|
||||
std::error_code ec;
|
||||
std::filesystem::rename(path_, new_path, ec);
|
||||
|
||||
if (ec) {
|
||||
LOG_ERRO("Failed to rename file (%s).", ec.message().c_str());
|
||||
|
||||
+9
-9
@@ -1,12 +1,12 @@
|
||||
#ifndef WEBCC_BODY_H_
|
||||
#define WEBCC_BODY_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "boost/filesystem/fstream.hpp"
|
||||
|
||||
#include "webcc/common.h"
|
||||
|
||||
namespace webcc {
|
||||
@@ -152,14 +152,14 @@ private:
|
||||
class FileBody : public Body {
|
||||
public:
|
||||
// For message to be sent out.
|
||||
FileBody(const Path& path, std::size_t chunk_size);
|
||||
FileBody(const std::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 Path& path, bool auto_delete = false);
|
||||
FileBody(const std::filesystem::path& path, bool auto_delete = false);
|
||||
|
||||
~FileBody() override;
|
||||
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
|
||||
void Dump(std::ostream& os, const std::string& prefix) const override;
|
||||
|
||||
const Path& path() const {
|
||||
const std::filesystem::path& path() const {
|
||||
return path_;
|
||||
}
|
||||
|
||||
@@ -186,17 +186,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 boost::filesystem::rename() for more details.
|
||||
bool Move(const Path& new_path);
|
||||
// See std::filesystem::rename() for more details.
|
||||
bool Move(const std::filesystem::path& new_path);
|
||||
|
||||
private:
|
||||
Path path_;
|
||||
std::filesystem::path path_;
|
||||
std::size_t chunk_size_;
|
||||
bool auto_delete_;
|
||||
|
||||
std::size_t size_; // File size in bytes
|
||||
|
||||
boost::filesystem::ifstream ifstream_;
|
||||
std::ifstream ifstream_;
|
||||
std::string chunk_;
|
||||
};
|
||||
|
||||
|
||||
+3
-2
@@ -191,7 +191,8 @@ FormPartPtr FormPart::New(const std::string& name, std::string&& data,
|
||||
return form_part;
|
||||
}
|
||||
|
||||
FormPartPtr FormPart::NewFile(const std::string& name, const Path& path,
|
||||
FormPartPtr FormPart::NewFile(const std::string& name,
|
||||
const std::filesystem::path& path,
|
||||
const std::string& media_type) {
|
||||
auto form_part = std::make_shared<FormPart>();
|
||||
|
||||
@@ -201,7 +202,7 @@ FormPartPtr FormPart::NewFile(const std::string& name, const Path& path,
|
||||
|
||||
// Determine file name from file path.
|
||||
// TODO: encoding
|
||||
form_part->file_name_ = path.filename().string(std::codecvt_utf8<wchar_t>());
|
||||
form_part->file_name_ = path.filename().string();
|
||||
|
||||
// Determine media type from file extension.
|
||||
// TODO: Default to "application/text"?
|
||||
|
||||
+4
-2
@@ -2,6 +2,7 @@
|
||||
#define WEBCC_COMMON_H_
|
||||
|
||||
#include <cassert>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -156,7 +157,8 @@ public:
|
||||
// Construct a file part.
|
||||
// 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 Path& path,
|
||||
static FormPartPtr NewFile(const std::string& name,
|
||||
const std::filesystem::path& path,
|
||||
const std::string& media_type = "");
|
||||
|
||||
// API: SERVER
|
||||
@@ -227,7 +229,7 @@ private:
|
||||
std::string name_;
|
||||
|
||||
// The path of the file to post.
|
||||
Path path_;
|
||||
std::filesystem::path path_;
|
||||
|
||||
// The original local file name.
|
||||
// E.g., "baby.jpg".
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include "boost/asio/buffer.hpp" // for const_buffer
|
||||
#include "boost/filesystem/path.hpp"
|
||||
|
||||
#include "webcc/config.h"
|
||||
|
||||
@@ -53,8 +52,6 @@ using Strings = std::vector<std::string>;
|
||||
// Could also be considered as arguments, so named as UrlArgs.
|
||||
using UrlArgs = std::vector<std::string>;
|
||||
|
||||
using Path = boost::filesystem::path;
|
||||
|
||||
using Payload = std::vector<boost::asio::const_buffer>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
+10
-15
@@ -6,6 +6,7 @@
|
||||
#include <chrono>
|
||||
#include <cstdarg>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
#include <iomanip> // for put_time
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
@@ -20,10 +21,6 @@
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
namespace webcc {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -36,7 +33,7 @@ static const char* kLevelNames[] = {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static FILE* FOpen(const bfs::path& path, bool overwrite) {
|
||||
static FILE* FOpen(const std::filesystem::path& path, bool overwrite) {
|
||||
#if (defined(_WIN32) || defined(_WIN64))
|
||||
return _wfopen(path.wstring().c_str(), overwrite ? L"w+" : L"a+");
|
||||
#else
|
||||
@@ -48,7 +45,7 @@ struct Logger {
|
||||
Logger() : file(nullptr), modes(0) {
|
||||
}
|
||||
|
||||
void Init(const bfs::path& path, int _modes) {
|
||||
void Init(const std::filesystem::path& path, int _modes) {
|
||||
modes = _modes;
|
||||
|
||||
// Create log file only if necessary.
|
||||
@@ -134,8 +131,6 @@ static const bool g_terminal_has_color = []() {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
// std::this_thread::get_id() returns a very long ID (same as pthread_self())
|
||||
// on Linux, e.g., 140219133990656. syscall(SYS_gettid) is much prefered because
|
||||
// it's shorter and the same as `ps -T -p <pid>` output.
|
||||
@@ -158,22 +153,22 @@ static std::string GetThreadID() {
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
static bfs::path InitLogPath(const bfs::path& dir) {
|
||||
static std::filesystem::path InitLogPath(const std::filesystem::path& dir) {
|
||||
if (dir.empty()) {
|
||||
return bfs::current_path() / WEBCC_LOG_FILE_NAME;
|
||||
return std::filesystem::current_path() / WEBCC_LOG_FILE_NAME;
|
||||
}
|
||||
|
||||
if (!bfs::exists(dir) || !bfs::is_directory(dir)) {
|
||||
boost::system::error_code ec;
|
||||
if (!bfs::create_directories(dir, ec) || ec) {
|
||||
return bfs::path();
|
||||
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{};
|
||||
}
|
||||
}
|
||||
|
||||
return (dir / WEBCC_LOG_FILE_NAME);
|
||||
}
|
||||
|
||||
void LogInit(const bfs::path& dir, int modes) {
|
||||
void LogInit(const std::filesystem::path& dir, int modes) {
|
||||
// Suppose this is called from the main thread.
|
||||
g_main_thread_id = DoGetThreadID();
|
||||
|
||||
|
||||
+7
-2
@@ -9,7 +9,12 @@
|
||||
#include <cstring> // for strrchr()
|
||||
#include <string>
|
||||
|
||||
#include "boost/filesystem/path.hpp"
|
||||
// Avoid include <filesystem> in the header.
|
||||
namespace std {
|
||||
namespace filesystem {
|
||||
class path;
|
||||
} // namespace filesystem
|
||||
} // namespace std
|
||||
|
||||
// Log levels.
|
||||
// VERB is similar to DEBUG commonly used by other projects.
|
||||
@@ -44,7 +49,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 boost::filesystem::path& dir, int modes);
|
||||
void LogInit(const std::filesystem::path& dir, int modes);
|
||||
|
||||
void Log(int level, const char* file, int line, const char* format, ...);
|
||||
|
||||
|
||||
+10
-6
@@ -1,18 +1,16 @@
|
||||
#include "webcc/parser.h"
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
#include "boost/filesystem/operations.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
#include "webcc/message.h"
|
||||
#include "webcc/string.h"
|
||||
#include "webcc/utility.h"
|
||||
|
||||
#if WEBCC_ENABLE_GZIP
|
||||
#include "webcc/gzip.h"
|
||||
#endif
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
namespace webcc {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -69,11 +67,17 @@ bool StringBodyHandler::Finish() {
|
||||
|
||||
bool FileBodyHandler::OpenFile() {
|
||||
try {
|
||||
temp_path_ = bfs::temp_directory_path() / bfs::unique_path();
|
||||
temp_path_ = std::filesystem::temp_directory_path();
|
||||
|
||||
// Generate a random string as file name.
|
||||
// A replacement of boost::filesystem::unique_path().
|
||||
temp_path_ /= string::RandomString(10);
|
||||
|
||||
LOG_VERB("Generate a temp path for streaming: %s",
|
||||
temp_path_.string().c_str());
|
||||
} catch (const bfs::filesystem_error&) {
|
||||
LOG_ERRO("Failed to generate temp path: %s", temp_path_.string().c_str());
|
||||
|
||||
} catch (const std::filesystem::filesystem_error&) {
|
||||
LOG_ERRO("Failed to generate temp path for streaming.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
#ifndef WEBCC_PARSER_H_
|
||||
#define WEBCC_PARSER_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "boost/filesystem/fstream.hpp"
|
||||
|
||||
#include "webcc/common.h"
|
||||
#include "webcc/globals.h"
|
||||
|
||||
@@ -82,8 +82,8 @@ public:
|
||||
|
||||
private:
|
||||
std::size_t streamed_size_ = 0;
|
||||
boost::filesystem::ofstream ofstream_;
|
||||
Path temp_path_;
|
||||
std::ofstream ofstream_;
|
||||
std::filesystem::path temp_path_;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -51,7 +51,7 @@ RequestPtr RequestBuilder::operator()() {
|
||||
return request;
|
||||
}
|
||||
|
||||
RequestBuilder& RequestBuilder::File(const webcc::Path& path,
|
||||
RequestBuilder& RequestBuilder::File(const std::filesystem::path& path,
|
||||
bool infer_media_type,
|
||||
std::size_t chunk_size) {
|
||||
body_.reset(new FileBody{ path, chunk_size });
|
||||
@@ -64,7 +64,7 @@ RequestBuilder& RequestBuilder::File(const webcc::Path& path,
|
||||
}
|
||||
|
||||
RequestBuilder& RequestBuilder::FormFile(const std::string& name,
|
||||
const webcc::Path& path,
|
||||
const std::filesystem::path& path,
|
||||
const std::string& media_type) {
|
||||
assert(!name.empty());
|
||||
return Form(FormPart::NewFile(name, path, media_type));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef WEBCC_REQUEST_BUILDER_H_
|
||||
#define WEBCC_REQUEST_BUILDER_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -128,7 +129,8 @@ public:
|
||||
|
||||
// Use the file content as body.
|
||||
// NOTE: Error::kFileError might be thrown.
|
||||
RequestBuilder& File(const webcc::Path& path, bool infer_media_type = true,
|
||||
RequestBuilder& File(const std::filesystem::path& path,
|
||||
bool infer_media_type = true,
|
||||
std::size_t chunk_size = 1024);
|
||||
|
||||
// Add a form part.
|
||||
@@ -138,7 +140,8 @@ public:
|
||||
}
|
||||
|
||||
// Add a form part of file.
|
||||
RequestBuilder& FormFile(const std::string& name, const webcc::Path& path,
|
||||
RequestBuilder& FormFile(const std::string& name,
|
||||
const std::filesystem::path& path,
|
||||
const std::string& media_type = "");
|
||||
|
||||
// Add a form part of string data.
|
||||
|
||||
@@ -43,7 +43,7 @@ ResponsePtr ResponseBuilder::operator()() {
|
||||
return response;
|
||||
}
|
||||
|
||||
ResponseBuilder& ResponseBuilder::File(const webcc::Path& path,
|
||||
ResponseBuilder& ResponseBuilder::File(const std::filesystem::path& path,
|
||||
bool infer_media_type,
|
||||
std::size_t chunk_size) {
|
||||
body_.reset(new FileBody{ path, chunk_size });
|
||||
|
||||
@@ -94,7 +94,8 @@ public:
|
||||
|
||||
// Use the file content as body.
|
||||
// NOTE: Error::kFileError might be thrown.
|
||||
ResponseBuilder& File(const webcc::Path& path, bool infer_media_type = true,
|
||||
ResponseBuilder& File(const std::filesystem::path& path,
|
||||
bool infer_media_type = true,
|
||||
std::size_t chunk_size = 1024);
|
||||
|
||||
ResponseBuilder& Header(const std::string& key, const std::string& value) {
|
||||
|
||||
+6
-8
@@ -1,24 +1,22 @@
|
||||
#include "webcc/server.h"
|
||||
|
||||
#include <csignal>
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
|
||||
#include "boost/filesystem/fstream.hpp"
|
||||
#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 bfs = boost::filesystem;
|
||||
namespace sfs = std::filesystem;
|
||||
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
|
||||
namespace webcc {
|
||||
|
||||
Server::Server(std::uint16_t port, const Path& doc_root)
|
||||
Server::Server(std::uint16_t port, const std::filesystem::path& doc_root)
|
||||
: port_(port), doc_root_(doc_root), file_chunk_size_(1024), running_(false),
|
||||
acceptor_(io_context_), signals_(io_context_) {
|
||||
AddSignals();
|
||||
@@ -298,8 +296,8 @@ bool Server::MatchViewOrStatic(const std::string& method,
|
||||
|
||||
// Try to match a static file.
|
||||
if (method == methods::kGet && !doc_root_.empty()) {
|
||||
Path path = doc_root_ / url;
|
||||
if (!bfs::is_directory(path) && bfs::exists(path)) {
|
||||
std::filesystem::path path = doc_root_ / url;
|
||||
if (!sfs::is_directory(path) && sfs::exists(path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -315,7 +313,7 @@ ResponsePtr Server::ServeStatic(RequestPtr request) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Path path = doc_root_ / request->url().path();
|
||||
std::filesystem::path path = doc_root_ / request->url().path();
|
||||
|
||||
try {
|
||||
// NOTE: FileBody might throw Error::kFileError.
|
||||
|
||||
+4
-2
@@ -1,6 +1,7 @@
|
||||
#ifndef WEBCC_SERVER_H_
|
||||
#define WEBCC_SERVER_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
@@ -19,7 +20,8 @@ namespace webcc {
|
||||
|
||||
class Server : public Router {
|
||||
public:
|
||||
explicit Server(std::uint16_t port, const Path& doc_root = {});
|
||||
explicit Server(std::uint16_t port,
|
||||
const std::filesystem::path& doc_root = {});
|
||||
|
||||
~Server() = default;
|
||||
|
||||
@@ -96,7 +98,7 @@ private:
|
||||
std::uint16_t port_;
|
||||
|
||||
// The directory with the static files to be served.
|
||||
Path doc_root_;
|
||||
std::filesystem::path doc_root_;
|
||||
|
||||
// The size of the chunk loaded into memory each time when serving a
|
||||
// static file.
|
||||
|
||||
+1
-4
@@ -15,7 +15,6 @@
|
||||
#include "boost/asio/connect.hpp"
|
||||
#include "boost/asio/read.hpp"
|
||||
#include "boost/asio/write.hpp"
|
||||
#include "boost/core/ignore_unused.hpp"
|
||||
|
||||
#include "webcc/logger.h"
|
||||
|
||||
@@ -26,9 +25,7 @@ namespace webcc {
|
||||
Socket::Socket(boost::asio::io_context& io_context) : socket_(io_context) {
|
||||
}
|
||||
|
||||
bool Socket::Connect(const std::string& host, const Endpoints& endpoints) {
|
||||
boost::ignore_unused(host);
|
||||
|
||||
bool Socket::Connect(const std::string& /*host*/, const Endpoints& endpoints) {
|
||||
boost::system::error_code ec;
|
||||
boost::asio::connect(socket_, endpoints, ec);
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "webcc/string.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace webcc {
|
||||
namespace string {
|
||||
|
||||
// See: https://stackoverflow.com/a/24586587
|
||||
std::string RandomString(std::size_t length) {
|
||||
static const char chrs[] =
|
||||
"0123456789"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
thread_local static std::mt19937 rg{ std::random_device{}() };
|
||||
thread_local static std::uniform_int_distribution<std::string::size_type>
|
||||
pick(0, sizeof(chrs) - 2);
|
||||
|
||||
std::string s;
|
||||
s.reserve(length);
|
||||
|
||||
while (length--) {
|
||||
s += chrs[pick(rg)];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
bool EqualsNoCase(const std::string& str1, const std::string& str2) {
|
||||
if (str1.size() != str2.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return std::equal(str1.begin(), str1.end(), str2.begin(), [](int c1, int c2) {
|
||||
return std::toupper(c1) == std::toupper(c2);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace string
|
||||
} // namespace webcc
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef WEBCC_STRING_H_
|
||||
#define WEBCC_STRING_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace webcc {
|
||||
namespace string {
|
||||
|
||||
// Get a randomly generated string with the given length.
|
||||
std::string RandomString(std::size_t length);
|
||||
|
||||
// TODO: What about std::wstring?
|
||||
bool EqualsNoCase(const std::string& str1, const std::string& str2);
|
||||
|
||||
template <class Container>
|
||||
void Split(const std::string& str, Container& cont) {
|
||||
std::istringstream iss(str);
|
||||
std::copy(std::istream_iterator<std::string>(iss),
|
||||
std::istream_iterator<std::string>(), std::back_inserter(cont));
|
||||
}
|
||||
|
||||
} // namespace string
|
||||
} // namespace webcc
|
||||
|
||||
#endif // WEBCC_STRING_H_
|
||||
+7
-7
@@ -1,18 +1,18 @@
|
||||
#include "webcc/utility.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iomanip> // for put_time
|
||||
#include <sstream>
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
#include "boost/filesystem/fstream.hpp"
|
||||
#include "boost/uuid/random_generator.hpp"
|
||||
#include "boost/uuid/uuid_io.hpp"
|
||||
|
||||
#include "webcc/version.h"
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
namespace webcc {
|
||||
namespace utility {
|
||||
|
||||
@@ -62,18 +62,18 @@ bool ToSize(const std::string& str, int base, std::size_t* size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t TellSize(const Path& path) {
|
||||
std::size_t TellSize(const std::filesystem::path& path) {
|
||||
// Flag "ate": seek to the end of stream immediately after open.
|
||||
bfs::ifstream stream{ path, std::ios::binary | std::ios::ate };
|
||||
std::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 Path& path, std::string* output) {
|
||||
bool ReadFile(const std::filesystem::path& path, std::string* output) {
|
||||
// Flag "ate": seek to the end of stream immediately after open.
|
||||
bfs::ifstream stream{ path, std::ios::binary | std::ios::ate };
|
||||
std::ifstream stream{ path, std::ios::binary | std::ios::ate };
|
||||
if (stream.fail()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+9
-2
@@ -5,6 +5,13 @@
|
||||
|
||||
#include "webcc/globals.h"
|
||||
|
||||
// Avoid include <filesystem> in the header.
|
||||
namespace std {
|
||||
namespace filesystem {
|
||||
class path;
|
||||
} // namespace filesystem
|
||||
} // namespace std
|
||||
|
||||
namespace webcc {
|
||||
namespace utility {
|
||||
|
||||
@@ -29,10 +36,10 @@ bool ToSize(const std::string& str, int base, std::size_t* size);
|
||||
|
||||
// Tell the size in bytes of the given file.
|
||||
// Return kInvalidLength (-1) on failure.
|
||||
std::size_t TellSize(const Path& path);
|
||||
std::size_t TellSize(const std::filesystem::path& path);
|
||||
|
||||
// Read entire file into string.
|
||||
bool ReadFile(const Path& path, std::string* output);
|
||||
bool ReadFile(const std::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.
|
||||
|
||||
Reference in New Issue
Block a user