From a0391575873d30fef1c1bd6063049a22360714ed Mon Sep 17 00:00:00 2001 From: An Tao Date: Sun, 12 Mar 2023 18:47:21 +0800 Subject: [PATCH] Fix loading configuration on windows (#1530) --- drogon_ctl/version.cc | 5 +++++ lib/src/ConfigAdapter.h | 3 ++- lib/src/ConfigAdapterManager.cc | 13 +++---------- lib/src/ConfigAdapterManager.h | 3 ++- lib/src/ConfigLoader.cc | 15 +++++++++++++-- lib/src/JsonConfigAdapter.cc | 8 +++----- lib/src/JsonConfigAdapter.h | 2 +- lib/src/YamlConfigAdapter.cc | 4 ++-- lib/src/YamlConfigAdapter.h | 2 +- 9 files changed, 32 insertions(+), 23 deletions(-) diff --git a/drogon_ctl/version.cc b/drogon_ctl/version.cc index e4777137..0deb27cb 100644 --- a/drogon_ctl/version.cc +++ b/drogon_ctl/version.cc @@ -65,4 +65,9 @@ void version::handleCommand(std::vector ¶meters) #endif std::cout << " c-ares: " << (trantor::Resolver::isCAresUsed() ? "yes\n" : "no\n"); +#ifdef HAS_YAML_CPP + std::cout << " yaml-cpp: yes\n"; +#else + std::cout << " yaml-cpp: no\n"; +#endif } diff --git a/lib/src/ConfigAdapter.h b/lib/src/ConfigAdapter.h index 03f16108..3f9b8a87 100644 --- a/lib/src/ConfigAdapter.h +++ b/lib/src/ConfigAdapter.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace drogon { @@ -10,7 +11,7 @@ class ConfigAdapter { public: virtual ~ConfigAdapter() = default; - virtual Json::Value getJson(const std::string &configFile) const + virtual Json::Value getJson(const std::string &content) const noexcept(false) = 0; virtual std::vector getExtensions() const = 0; }; diff --git a/lib/src/ConfigAdapterManager.cc b/lib/src/ConfigAdapterManager.cc index 147fc5e2..d49f7847 100644 --- a/lib/src/ConfigAdapterManager.cc +++ b/lib/src/ConfigAdapterManager.cc @@ -20,23 +20,16 @@ ConfigAdapterManager &ConfigAdapterManager::instance() return instance; } -Json::Value ConfigAdapterManager::getJson(const std::string &configFile) const - noexcept(false) +Json::Value ConfigAdapterManager::getJson(const std::string &content, + std::string ext) const noexcept(false) { - auto pos = configFile.find_last_of('.'); - if (pos == std::string::npos) - { - throw std::runtime_error("Invalid config file name!"); - } - auto ext = configFile.substr(pos + 1); - // convert ext to lower case std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); auto it = adapters_.find(ext); if (it == adapters_.end()) { throw std::runtime_error("No valid parser for this config file!"); } - return it->second->getJson(configFile); + return it->second->getJson(content); } ConfigAdapterManager::ConfigAdapterManager() diff --git a/lib/src/ConfigAdapterManager.h b/lib/src/ConfigAdapterManager.h index 73b97178..94f61e26 100644 --- a/lib/src/ConfigAdapterManager.h +++ b/lib/src/ConfigAdapterManager.h @@ -8,7 +8,8 @@ class ConfigAdapterManager { public: static ConfigAdapterManager &instance(); - Json::Value getJson(const std::string &configFile) const noexcept(false); + Json::Value getJson(const std::string &content, std::string ext) const + noexcept(false); private: ConfigAdapterManager(); diff --git a/lib/src/ConfigLoader.cc b/lib/src/ConfigLoader.cc index 3f63853a..585712b9 100644 --- a/lib/src/ConfigLoader.cc +++ b/lib/src/ConfigLoader.cc @@ -117,10 +117,21 @@ ConfigLoader::ConfigLoader(const std::string &configFile) configFile); } configFile_ = configFile; + auto pos = configFile.find_last_of('.'); + if (pos == std::string::npos) + { + throw std::runtime_error("Invalid config file name!"); + } + auto ext = configFile.substr(pos + 1); + std::ifstream infile(drogon::utils::toNativePath(configFile).c_str(), + std::ifstream::in); + // get the content of the infile + std::string content((std::istreambuf_iterator(infile)), + std::istreambuf_iterator()); try { - auto filename = drogon::utils::toNativePath(configFile); - configJsonRoot_ = ConfigAdapterManager::instance().getJson(configFile); + configJsonRoot_ = + ConfigAdapterManager::instance().getJson(content, std::move(ext)); } catch (std::exception &e) { diff --git a/lib/src/JsonConfigAdapter.cc b/lib/src/JsonConfigAdapter.cc index 08786e71..2647dfb9 100644 --- a/lib/src/JsonConfigAdapter.cc +++ b/lib/src/JsonConfigAdapter.cc @@ -2,17 +2,15 @@ #include using namespace drogon; -Json::Value JsonConfigAdapter::getJson(const std::string &configFile) const +Json::Value JsonConfigAdapter::getJson(const std::string &content) const noexcept(false) { Json::Value root; Json::Reader reader; - std::ifstream in(configFile, std::ios::binary); - if (!in.is_open()) + if (!reader.parse(content, root)) { - throw std::runtime_error("Cannot open config file!"); + throw std::runtime_error("Failed to parse JSON"); } - in >> root; return root; } std::vector JsonConfigAdapter::getExtensions() const diff --git a/lib/src/JsonConfigAdapter.h b/lib/src/JsonConfigAdapter.h index aa1b058c..aca59b47 100644 --- a/lib/src/JsonConfigAdapter.h +++ b/lib/src/JsonConfigAdapter.h @@ -7,7 +7,7 @@ class JsonConfigAdapter : public ConfigAdapter public: JsonConfigAdapter() = default; ~JsonConfigAdapter() override = default; - Json::Value getJson(const std::string &configFile) const + Json::Value getJson(const std::string &content) const noexcept(false) override; std::vector getExtensions() const override; }; diff --git a/lib/src/YamlConfigAdapter.cc b/lib/src/YamlConfigAdapter.cc index b80eefa4..c6a82ef2 100644 --- a/lib/src/YamlConfigAdapter.cc +++ b/lib/src/YamlConfigAdapter.cc @@ -95,12 +95,12 @@ struct convert } // namespace YAML #endif -Json::Value YamlConfigAdapter::getJson(const std::string &configFile) const +Json::Value YamlConfigAdapter::getJson(const std::string &content) const noexcept(false) { #if HAS_YAML_CPP // parse yaml file - YAML::Node config = YAML::LoadFile(configFile); + YAML::Node config = YAML::Load(content); if (!config.IsNull()) { return config.as(); diff --git a/lib/src/YamlConfigAdapter.h b/lib/src/YamlConfigAdapter.h index 9a48ae9b..623e28d1 100644 --- a/lib/src/YamlConfigAdapter.h +++ b/lib/src/YamlConfigAdapter.h @@ -7,7 +7,7 @@ class YamlConfigAdapter : public ConfigAdapter public: YamlConfigAdapter() = default; ~YamlConfigAdapter() override = default; - Json::Value getJson(const std::string &configFile) const + Json::Value getJson(const std::string &content) const noexcept(false) override; std::vector getExtensions() const override; };