/* Copyright 2020, Michele Santullo * This file is part of orotool. * * Orotool is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Orotool is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Orotool. If not, see . */ #include "app_config.hpp" #include "orotool_config.hpp" #include #include #include #include #include #include #include namespace duck { namespace { constexpr const char g_db_path_sect[] = "system"; constexpr const char g_db_path[] = "db_path"; constexpr const char g_worker_threads_sect[] = "system"; constexpr const char g_worker_threads[] = "worker_threads"; std::string whole_ini() { std::ifstream input(g_config_file_path); input >> std::noskipws; return { std::istream_iterator(input), std::istream_iterator() }; } std::string_view value_ifp ( const kamokan::IniFile& ini, std::string_view section, std::string_view key, std::string_view def, bool allow_empty ) { const auto& map = ini.parsed(); auto it_section = map.find(section); if (map.end() == it_section) return def; auto it_setting = it_section->second.find(key); if (it_section->second.end() == it_setting) return def; if (not allow_empty and it_setting->second.empty()) return def; else return it_setting->second; } } //unnamed namespace AppConfig::AppConfig() : m_ini(whole_ini()) { } AppConfig::~AppConfig() noexcept = default; std::string_view AppConfig::db_path() const { return value_ifp(m_ini, g_db_path_sect, g_db_path, g_def_sqlite_db_name, false); } std::size_t AppConfig::worker_threads() const { std::string_view opt_name(g_worker_threads); std::string_view val = value_ifp(m_ini, g_worker_threads_sect, opt_name, g_def_worker_threads, false); if (val == "max") { return std::max(3U, std::thread::hardware_concurrency()) - 1; } else { try { const std::size_t num = std::stoul(std::string(val.data(), val.size())); const std::size_t hard_max = 4U * std::thread::hardware_concurrency(); return std::max(2U, std::min(num, hard_max)); } catch (const std::logic_error& err) { std::cerr << "Error reading setting " << opt_name << ": " << err.what() << '\n'; return std::stoul(g_def_worker_threads); } } } } //namespace duck