diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/poco/Util/src | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/poco/Util/src')
27 files changed, 5738 insertions, 0 deletions
diff --git a/contrib/libs/poco/Util/src/AbstractConfiguration.cpp b/contrib/libs/poco/Util/src/AbstractConfiguration.cpp new file mode 100644 index 0000000000..2751754a60 --- /dev/null +++ b/contrib/libs/poco/Util/src/AbstractConfiguration.cpp @@ -0,0 +1,536 @@ +// +// AbstractConfiguration.cpp +// +// Library: Util +// Package: Configuration +// Module: AbstractConfiguration +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/AbstractConfiguration.h" +#include "Poco/Util/ConfigurationView.h" +#include "Poco/Exception.h" +#include "Poco/NumberParser.h" +#include "Poco/NumberFormatter.h" +#include "Poco/String.h" + + +using Poco::Mutex; +using Poco::NotFoundException; +using Poco::SyntaxException; +using Poco::CircularReferenceException; +using Poco::NumberParser; +using Poco::NumberFormatter; +using Poco::icompare; + + +namespace Poco { +namespace Util { + + +AbstractConfiguration::AbstractConfiguration(): + _depth(0), + _eventsEnabled(true) +{ +} + + +AbstractConfiguration::~AbstractConfiguration() +{ +} + + +bool AbstractConfiguration::hasProperty(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + return getRaw(key, value); +} + + +bool AbstractConfiguration::hasOption(const std::string& key) const +{ + return hasProperty(key); +} + + +bool AbstractConfiguration::has(const std::string& key) const +{ + return hasProperty(key); +} + + +std::string AbstractConfiguration::getString(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return internalExpand(value); + else + throw NotFoundException(key); +} + + +std::string AbstractConfiguration::getString(const std::string& key, const std::string& defaultValue) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return internalExpand(value); + else + return defaultValue; +} + + +std::string AbstractConfiguration::getRawString(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return value; + else + throw NotFoundException(key); +} + + +std::string AbstractConfiguration::getRawString(const std::string& key, const std::string& defaultValue) const +{ + + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return value; + else + return defaultValue; +} + + +int AbstractConfiguration::getInt(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseInt(internalExpand(value)); + else + throw NotFoundException(key); +} + + +int AbstractConfiguration::getInt(const std::string& key, int defaultValue) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseInt(internalExpand(value)); + else + return defaultValue; +} + + +unsigned AbstractConfiguration::getUInt(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseUInt(internalExpand(value)); + else + throw NotFoundException(key); +} + + +unsigned AbstractConfiguration::getUInt(const std::string& key, unsigned defaultValue) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseUInt(internalExpand(value)); + else + return defaultValue; +} + + +#if defined(POCO_HAVE_INT64) + + +Int64 AbstractConfiguration::getInt64(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseInt64(internalExpand(value)); + else + throw NotFoundException(key); +} + + +Int64 AbstractConfiguration::getInt64(const std::string& key, Int64 defaultValue) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseInt64(internalExpand(value)); + else + return defaultValue; +} + + +UInt64 AbstractConfiguration::getUInt64(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseUInt64(internalExpand(value)); + else + throw NotFoundException(key); +} + + +UInt64 AbstractConfiguration::getUInt64(const std::string& key, UInt64 defaultValue) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseUInt64(internalExpand(value)); + else + return defaultValue; +} + + +#endif // defined(POCO_HAVE_INT64) + + +double AbstractConfiguration::getDouble(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return NumberParser::parseFloat(internalExpand(value)); + else + throw NotFoundException(key); +} + + +double AbstractConfiguration::getDouble(const std::string& key, double defaultValue) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return NumberParser::parseFloat(internalExpand(value)); + else + return defaultValue; +} + + +bool AbstractConfiguration::getBool(const std::string& key) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseBool(internalExpand(value)); + else + throw NotFoundException(key); +} + + +bool AbstractConfiguration::getBool(const std::string& key, bool defaultValue) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return parseBool(internalExpand(value)); + else + return defaultValue; +} + + +void AbstractConfiguration::setString(const std::string& key, const std::string& value) +{ + setRawWithEvent(key, value); +} + + +void AbstractConfiguration::setInt(const std::string& key, int value) +{ + setRawWithEvent(key, NumberFormatter::format(value)); +} + + +void AbstractConfiguration::setUInt(const std::string& key, unsigned int value) +{ + setRawWithEvent(key, NumberFormatter::format(value)); +} + + +#if defined(POCO_HAVE_INT64) + + +void AbstractConfiguration::setInt64(const std::string& key, Int64 value) +{ + Mutex::ScopedLock lock(_mutex); + + setRawWithEvent(key, NumberFormatter::format(value)); +} + + +void AbstractConfiguration::setUInt64(const std::string& key, UInt64 value) +{ + Mutex::ScopedLock lock(_mutex); + + setRawWithEvent(key, NumberFormatter::format(value)); +} + + +#endif // defined(POCO_HAVE_INT64) + + +void AbstractConfiguration::setDouble(const std::string& key, double value) +{ + setRawWithEvent(key, NumberFormatter::format(value)); +} + + +void AbstractConfiguration::setBool(const std::string& key, bool value) +{ + setRawWithEvent(key, value ? "true" : "false"); +} + + +void AbstractConfiguration::keys(Keys& range) const +{ + Mutex::ScopedLock lock(_mutex); + + std::string key; + range.clear(); + enumerate(key, range); +} + + +void AbstractConfiguration::keys(const std::string& key, Keys& range) const +{ + Mutex::ScopedLock lock(_mutex); + + range.clear(); + enumerate(key, range); +} + + +const AbstractConfiguration* AbstractConfiguration::createView(const std::string& prefix) const +{ + return new ConfigurationView(prefix, const_cast<AbstractConfiguration*>(this)); +} + + +AbstractConfiguration* AbstractConfiguration::createView(const std::string& prefix) +{ + return new ConfigurationView(prefix, this); +} + + +namespace +{ + class AutoCounter + { + public: + AutoCounter(int& count): _count(count) + { + ++_count; + } + + ~AutoCounter() + { + --_count; + } + + private: + int& _count; + }; +} + + +std::string AbstractConfiguration::expand(const std::string& value) const +{ + Mutex::ScopedLock lock(_mutex); + + return internalExpand(value); +} + + +void AbstractConfiguration::remove(const std::string& key) +{ + if (_eventsEnabled) + { + propertyRemoving(this, key); + } + { + + Mutex::ScopedLock lock(_mutex); + removeRaw(key); + } + if (_eventsEnabled) + { + propertyRemoved(this, key); + } +} + + +void AbstractConfiguration::enableEvents(bool enable) +{ + _eventsEnabled = enable; +} + + +bool AbstractConfiguration::eventsEnabled() const +{ + return _eventsEnabled; +} + + +void AbstractConfiguration::removeRaw(const std::string& /*key*/) +{ + throw Poco::NotImplementedException("removeRaw()"); +} + + +std::string AbstractConfiguration::internalExpand(const std::string& value) const +{ + AutoCounter counter(_depth); + if (_depth > 10) throw CircularReferenceException("Too many property references encountered"); + return uncheckedExpand(value); +} + + +std::string AbstractConfiguration::uncheckedExpand(const std::string& value) const +{ + std::string result; + std::string::const_iterator it = value.begin(); + std::string::const_iterator end = value.end(); + while (it != end) + { + if (*it == '$') + { + ++it; + if (it != end && *it == '{') + { + ++it; + std::string prop; + while (it != end && *it != '}') prop += *it++; + if (it != end) ++it; + std::string rawValue; + if (getRaw(prop, rawValue)) + { + result.append(internalExpand(rawValue)); + } + else + { + result.append("${"); + result.append(prop); + result.append("}"); + } + } + else result += '$'; + } + else result += *it++; + } + return result; +} + + +int AbstractConfiguration::parseInt(const std::string& value) +{ + if ((value.compare(0, 2, "0x") == 0) || (value.compare(0, 2, "0X") == 0)) + return static_cast<int>(NumberParser::parseHex(value)); + else + return NumberParser::parse(value); +} + + +unsigned AbstractConfiguration::parseUInt(const std::string& value) +{ + if ((value.compare(0, 2, "0x") == 0) || (value.compare(0, 2, "0X") == 0)) + return NumberParser::parseHex(value); + else + return NumberParser::parseUnsigned(value); +} + + +Int64 AbstractConfiguration::parseInt64(const std::string& value) +{ + if ((value.compare(0, 2, "0x") == 0) || (value.compare(0, 2, "0X") == 0)) + return static_cast<Int64>(NumberParser::parseHex64(value)); + else + return NumberParser::parse64(value); +} + + +UInt64 AbstractConfiguration::parseUInt64(const std::string& value) +{ + if ((value.compare(0, 2, "0x") == 0) || (value.compare(0, 2, "0X") == 0)) + return NumberParser::parseHex64(value); + else + return NumberParser::parseUnsigned64(value); +} + + +bool AbstractConfiguration::parseBool(const std::string& value) +{ + int n; + if (NumberParser::tryParse(value, n)) + return n != 0; + else if (icompare(value, "true") == 0) + return true; + else if (icompare(value, "yes") == 0) + return true; + else if (icompare(value, "on") == 0) + return true; + else if (icompare(value, "false") == 0) + return false; + else if (icompare(value, "no") == 0) + return false; + else if (icompare(value, "off") == 0) + return false; + else + throw SyntaxException("Cannot convert to boolean", value); +} + + +void AbstractConfiguration::setRawWithEvent(const std::string& key, std::string value) +{ + KeyValue kv(key, value); + if (_eventsEnabled) + { + propertyChanging(this, kv); + } + { + Mutex::ScopedLock lock(_mutex); + setRaw(key, value); + } + if (_eventsEnabled) + { + propertyChanged(this, kv); + } +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/Application.cpp b/contrib/libs/poco/Util/src/Application.cpp new file mode 100644 index 0000000000..c584ea7011 --- /dev/null +++ b/contrib/libs/poco/Util/src/Application.cpp @@ -0,0 +1,568 @@ +// +// Application.cpp +// +// Library: Util +// Package: Application +// Module: Application +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/Application.h" +#include "Poco/Util/SystemConfiguration.h" +#include "Poco/Util/MapConfiguration.h" +#include "Poco/Util/PropertyFileConfiguration.h" +#include "Poco/Util/IniFileConfiguration.h" +#ifndef POCO_UTIL_NO_XMLCONFIGURATION +#include "Poco/Util/XMLConfiguration.h" +#endif +#ifndef POCO_UTIL_NO_JSONCONFIGURATION +#include "Poco/Util/JSONConfiguration.h" +#endif +#include "Poco/Util/LoggingSubsystem.h" +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionProcessor.h" +#include "Poco/Util/Validator.h" +#include "Poco/Environment.h" +#include "Poco/Exception.h" +#include "Poco/NumberFormatter.h" +#include "Poco/File.h" +#include "Poco/Path.h" +#include "Poco/String.h" +#include "Poco/ConsoleChannel.h" +#include "Poco/AutoPtr.h" +#if defined(POCO_OS_FAMILY_WINDOWS) +#include "Poco/UnWindows.h" +#endif +#if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS) +#include "Poco/SignalHandler.h" +#endif +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) +#include "Poco/UnicodeConverter.h" +#endif + + +using Poco::Logger; +using Poco::Path; +using Poco::File; +using Poco::Environment; +using Poco::SystemException; +using Poco::ConsoleChannel; +using Poco::NumberFormatter; +using Poco::AutoPtr; +using Poco::icompare; + + +namespace Poco { +namespace Util { + + +Application* Application::_pInstance = 0; + + +Application::Application(): + _pConfig(new LayeredConfiguration), + _initialized(false), + _unixOptions(true), + _pLogger(&Logger::get("ApplicationStartup")), + _stopOptionsProcessing(false) +{ + setup(); +} + + +Application::Application(int argc, char* argv[]): + _pConfig(new LayeredConfiguration), + _initialized(false), + _unixOptions(true), + _pLogger(&Logger::get("ApplicationStartup")), + _stopOptionsProcessing(false) +{ + setup(); + init(argc, argv); +} + + +Application::~Application() +{ + _pInstance = 0; +} + + +void Application::setup() +{ + poco_assert (_pInstance == 0); + + _pConfig->add(new SystemConfiguration, PRIO_SYSTEM, false, false); + _pConfig->add(new MapConfiguration, PRIO_APPLICATION, true, false); + + addSubsystem(new LoggingSubsystem); + +#if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS) + _workingDirAtLaunch = Path::current(); + + #if !defined(_DEBUG) + Poco::SignalHandler::install(); + #endif +#else + setUnixOptions(false); +#endif + + _pInstance = this; + + AutoPtr<ConsoleChannel> pCC = new ConsoleChannel; + Logger::setChannel("", pCC); +} + + +void Application::addSubsystem(Subsystem* pSubsystem) +{ + poco_check_ptr (pSubsystem); + + _subsystems.push_back(pSubsystem); +} + + +void Application::init(int argc, char* argv[]) +{ + setArgs(argc, argv); + init(); +} + + +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) +void Application::init(int argc, wchar_t* argv[]) +{ + std::vector<std::string> args; + for (int i = 0; i < argc; ++i) + { + std::string arg; + Poco::UnicodeConverter::toUTF8(argv[i], arg); + args.push_back(arg); + } + init(args); +} +#endif + + +void Application::init(const ArgVec& args) +{ + setArgs(args); + init(); +} + + +void Application::init() +{ + Path appPath; + getApplicationPath(appPath); + _pConfig->setString("application.path", appPath.toString()); + _pConfig->setString("application.name", appPath.getFileName()); + _pConfig->setString("application.baseName", appPath.getBaseName()); + _pConfig->setString("application.dir", appPath.parent().toString()); + _pConfig->setString("application.configDir", Path::configHome() + appPath.getBaseName() + Path::separator()); + _pConfig->setString("application.cacheDir", Path::cacheHome() + appPath.getBaseName() + Path::separator()); + _pConfig->setString("application.tempDir", Path::tempHome() + appPath.getBaseName() + Path::separator()); + _pConfig->setString("application.dataDir", Path::dataHome() + appPath.getBaseName() + Path::separator()); + processOptions(); +} + + +const char* Application::name() const +{ + return "Application"; +} + + +void Application::initialize(Application& self) +{ + for (SubsystemVec::iterator it = _subsystems.begin(); it != _subsystems.end(); ++it) + { + _pLogger->debug(std::string("Initializing subsystem: ") + (*it)->name()); + (*it)->initialize(self); + } + _initialized = true; +} + + +void Application::uninitialize() +{ + if (_initialized) + { + for (SubsystemVec::reverse_iterator it = _subsystems.rbegin(); it != _subsystems.rend(); ++it) + { + _pLogger->debug(std::string("Uninitializing subsystem: ") + (*it)->name()); + (*it)->uninitialize(); + } + _initialized = false; + } +} + + +void Application::reinitialize(Application& self) +{ + for (SubsystemVec::iterator it = _subsystems.begin(); it != _subsystems.end(); ++it) + { + _pLogger->debug(std::string("Re-initializing subsystem: ") + (*it)->name()); + (*it)->reinitialize(self); + } +} + + +void Application::setUnixOptions(bool flag) +{ + _unixOptions = flag; +} + + +int Application::loadConfiguration(int priority) +{ + int n = 0; + Path appPath; + getApplicationPath(appPath); + Path confPath; + if (findAppConfigFile(appPath.getBaseName(), "properties", confPath)) + { + _pConfig->add(new PropertyFileConfiguration(confPath.toString()), priority, false, false); + ++n; + } +#ifndef POCO_UTIL_NO_INIFILECONFIGURATION + if (findAppConfigFile(appPath.getBaseName(), "ini", confPath)) + { + _pConfig->add(new IniFileConfiguration(confPath.toString()), priority, false, false); + ++n; + } +#endif +#ifndef POCO_UTIL_NO_JSONCONFIGURATION + if (findAppConfigFile(appPath.getBaseName(), "json", confPath)) + { + _pConfig->add(new JSONConfiguration(confPath.toString()), priority, false, false); + ++n; + } +#endif +#ifndef POCO_UTIL_NO_XMLCONFIGURATION + if (findAppConfigFile(appPath.getBaseName(), "xml", confPath)) + { + _pConfig->add(new XMLConfiguration(confPath.toString()), priority, false, false); + ++n; + } +#endif + if (n > 0) + { + if (!confPath.isAbsolute()) + _pConfig->setString("application.configDir", confPath.absolute().parent().toString()); + else + _pConfig->setString("application.configDir", confPath.parent().toString()); + } + return n; +} + + +void Application::loadConfiguration(const std::string& path, int priority) +{ + int n = 0; + Path confPath(path); + std::string ext = confPath.getExtension(); + if (icompare(ext, "properties") == 0) + { + _pConfig->add(new PropertyFileConfiguration(confPath.toString()), priority, false, false); + ++n; + } +#ifndef POCO_UTIL_NO_INIFILECONFIGURATION + else if (icompare(ext, "ini") == 0) + { + _pConfig->add(new IniFileConfiguration(confPath.toString()), priority, false, false); + ++n; + } +#endif +#ifndef POCO_UTIL_NO_JSONCONFIGURATION + else if (icompare(ext, "json") == 0) + { + _pConfig->add(new JSONConfiguration(confPath.toString()), priority, false, false); + ++n; + } +#endif +#ifndef POCO_UTIL_NO_XMLCONFIGURATION + else if (icompare(ext, "xml") == 0) + { + _pConfig->add(new XMLConfiguration(confPath.toString()), priority, false, false); + ++n; + } +#endif + else throw Poco::InvalidArgumentException("Unsupported configuration file type", ext); + + if (n > 0 && !_pConfig->has("application.configDir")) + { + if (!confPath.isAbsolute()) + _pConfig->setString("application.configDir", confPath.absolute().parent().toString()); + else + _pConfig->setString("application.configDir", confPath.parent().toString()); + } +} + + +std::string Application::commandName() const +{ + return _pConfig->getString("application.baseName"); +} + + +std::string Application::commandPath() const +{ + return _pConfig->getString("application.path"); +} + + +void Application::stopOptionsProcessing() +{ + _stopOptionsProcessing = true; +} + + +int Application::run() +{ + int rc = EXIT_CONFIG; + initialize(*this); + + try + { + rc = EXIT_SOFTWARE; + rc = main(_unprocessedArgs); + } + catch (Poco::Exception& exc) + { + logger().log(exc); + } + catch (std::exception& exc) + { + logger().error(exc.what()); + } + catch (...) + { + logger().fatal("system exception"); + } + + uninitialize(); + return rc; +} + + +int Application::main(const ArgVec& /*args*/) +{ + return EXIT_OK; +} + + +void Application::setArgs(int argc, char* argv[]) +{ + _command = argv[0]; + _pConfig->setInt("application.argc", argc); + _unprocessedArgs.reserve(argc); + std::string argvKey = "application.argv["; + for (int i = 0; i < argc; ++i) + { + std::string arg(argv[i]); + _pConfig->setString(argvKey + NumberFormatter::format(i) + "]", arg); + _unprocessedArgs.push_back(arg); + } +} + + +void Application::setArgs(const ArgVec& args) +{ + poco_assert (!args.empty()); + + _command = args[0]; + _pConfig->setInt("application.argc", (int) args.size()); + _unprocessedArgs = args; + std::string argvKey = "application.argv["; + for (int i = 0; i < args.size(); ++i) + { + _pConfig->setString(argvKey + NumberFormatter::format(i) + "]", args[i]); + } +} + + +void Application::processOptions() +{ + defineOptions(_options); + OptionProcessor processor(_options); + processor.setUnixStyle(_unixOptions); + _argv = _unprocessedArgs; + _unprocessedArgs.erase(_unprocessedArgs.begin()); + ArgVec::iterator it = _unprocessedArgs.begin(); + while (it != _unprocessedArgs.end() && !_stopOptionsProcessing) + { + std::string name; + std::string value; + if (processor.process(*it, name, value)) + { + if (!name.empty()) // "--" option to end options processing or deferred argument + { + handleOption(name, value); + } + it = _unprocessedArgs.erase(it); + } + else ++it; + } + if (!_stopOptionsProcessing) + processor.checkRequired(); +} + + +void Application::getApplicationPath(Poco::Path& appPath) const +{ +#if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS) + if (_command.find('/') != std::string::npos) + { + Path path(_command); + if (path.isAbsolute()) + { + appPath = path; + } + else + { + appPath = _workingDirAtLaunch; + appPath.append(path); + } + } + else + { + if (!Path::find(Environment::get("PATH"), _command, appPath)) + appPath = Path(_workingDirAtLaunch, _command); + appPath.makeAbsolute(); + } +#elif defined(POCO_OS_FAMILY_WINDOWS) + #if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) + wchar_t path[1024]; + int n = GetModuleFileNameW(0, path, sizeof(path)/sizeof(wchar_t)); + if (n > 0) + { + std::string p; + Poco::UnicodeConverter::toUTF8(path, p); + appPath = p; + } + else throw SystemException("Cannot get application file name."); + #else + char path[1024]; + int n = GetModuleFileNameA(0, path, sizeof(path)); + if (n > 0) + appPath = path; + else + throw SystemException("Cannot get application file name."); + #endif +#else + appPath = _command; +#endif +} + + +bool Application::findFile(Poco::Path& path) const +{ + if (path.isAbsolute()) return true; + + Path appPath; + getApplicationPath(appPath); + Path base = appPath.parent(); + do + { + Path p(base, path); + File f(p); + if (f.exists()) + { + path = p; + return true; + } + if (base.depth() > 0) base.popDirectory(); + } + while (base.depth() > 0); + return false; +} + + +bool Application::findAppConfigFile(const std::string& appName, const std::string& extension, Path& path) const +{ + poco_assert (!appName.empty()); + + Path p(appName); + p.setExtension(extension); + bool found = findFile(p); + if (!found) + { +#if defined(_DEBUG) + if (appName[appName.length() - 1] == 'd') + { + p.setBaseName(appName.substr(0, appName.length() - 1)); + found = findFile(p); + } +#endif + } + if (found) + path = p; + return found; +} + + +bool Application::findAppConfigFile(const Path& basePath, const std::string& appName, const std::string& extension, Path& path) const +{ + poco_assert (!appName.empty()); + + Path p(basePath,appName); + p.setExtension(extension); + bool found = findFile(p); + if (!found) + { +#if defined(_DEBUG) + if (appName[appName.length() - 1] == 'd') + { + p.setBaseName(appName.substr(0, appName.length() - 1)); + found = findFile(p); + } +#endif + } + if (found) + path = p; + return found; +} + + +void Application::defineOptions(OptionSet& options) +{ + for (SubsystemVec::iterator it = _subsystems.begin(); it != _subsystems.end(); ++it) + { + (*it)->defineOptions(options); + } +} + + +void Application::handleOption(const std::string& name, const std::string& value) +{ + const Option& option = _options.getOption(name); + if (option.validator()) + { + option.validator()->validate(option, value); + } + if (!option.binding().empty()) + { + AbstractConfiguration* pConfig = option.config(); + if (!pConfig) pConfig = &config(); + pConfig->setString(option.binding(), value); + } + if (option.callback()) + { + option.callback()->invoke(name, value); + } +} + + +void Application::setLogger(Logger& logger) +{ + _pLogger = &logger; +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/ConfigurationMapper.cpp b/contrib/libs/poco/Util/src/ConfigurationMapper.cpp new file mode 100644 index 0000000000..d76f9c0b6d --- /dev/null +++ b/contrib/libs/poco/Util/src/ConfigurationMapper.cpp @@ -0,0 +1,101 @@ +// +// ConfigurationMapper.cpp +// +// Library: Util +// Package: Configuration +// Module: ConfigurationMapper +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/ConfigurationMapper.h" + + +namespace Poco { +namespace Util { + + +ConfigurationMapper::ConfigurationMapper(const std::string& fromPrefix, const std::string& toPrefix, AbstractConfiguration* pConfig): + _fromPrefix(fromPrefix), + _toPrefix(toPrefix), + _pConfig(pConfig) +{ + poco_check_ptr (pConfig); + + if (!_fromPrefix.empty()) _fromPrefix += '.'; + if (!_toPrefix.empty()) _toPrefix += '.'; + + _pConfig->duplicate(); +} + + +ConfigurationMapper::~ConfigurationMapper() +{ + _pConfig->release(); +} + + +bool ConfigurationMapper::getRaw(const std::string& key, std::string& value) const +{ + std::string translatedKey = translateKey(key); + return _pConfig->getRaw(translatedKey, value); +} + + +void ConfigurationMapper::setRaw(const std::string& key, const std::string& value) +{ + std::string translatedKey = translateKey(key); + _pConfig->setRaw(translatedKey, value); +} + + +void ConfigurationMapper::enumerate(const std::string& key, Keys& range) const +{ + std::string cKey(key); + if (!cKey.empty()) cKey += '.'; + std::string::size_type keyLen = cKey.length(); + if (keyLen < _toPrefix.length()) + { + if (_toPrefix.compare(0, keyLen, cKey) == 0) + { + std::string::size_type pos = _toPrefix.find_first_of('.', keyLen); + poco_assert_dbg(pos != std::string::npos); + range.push_back(_toPrefix.substr(keyLen, pos - keyLen)); + } + } + else + { + std::string translatedKey; + if (cKey == _toPrefix) + { + translatedKey = _fromPrefix; + if (!translatedKey.empty()) + translatedKey.resize(translatedKey.length() - 1); + } + else translatedKey = translateKey(key); + _pConfig->enumerate(translatedKey, range); + } +} + + +void ConfigurationMapper::removeRaw(const std::string& key) +{ + std::string translatedKey = translateKey(key); + _pConfig->remove(translatedKey); +} + + +std::string ConfigurationMapper::translateKey(const std::string& key) const +{ + std::string result(key); + if (result.compare(0, _toPrefix.size(), _toPrefix) == 0) + result.replace(0, _toPrefix.size(), _fromPrefix); + return result; +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/ConfigurationView.cpp b/contrib/libs/poco/Util/src/ConfigurationView.cpp new file mode 100644 index 0000000000..008a24f489 --- /dev/null +++ b/contrib/libs/poco/Util/src/ConfigurationView.cpp @@ -0,0 +1,75 @@ +// +// ConfigurationView.cpp +// +// Library: Util +// Package: Configuration +// Module: ConfigurationView +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/ConfigurationView.h" + + +namespace Poco { +namespace Util { + + +ConfigurationView::ConfigurationView(const std::string& prefix, AbstractConfiguration* pConfig): + _prefix(prefix), + _pConfig(pConfig) +{ + poco_check_ptr (pConfig); + + _pConfig->duplicate(); +} + + +ConfigurationView::~ConfigurationView() +{ + _pConfig->release(); +} + + +bool ConfigurationView::getRaw(const std::string& key, std::string& value) const +{ + std::string translatedKey = translateKey(key); + return _pConfig->getRaw(translatedKey, value) || _pConfig->getRaw(key, value); +} + + +void ConfigurationView::setRaw(const std::string& key, const std::string& value) +{ + std::string translatedKey = translateKey(key); + _pConfig->setRaw(translatedKey, value); +} + + +void ConfigurationView::enumerate(const std::string& key, Keys& range) const +{ + std::string translatedKey = translateKey(key); + _pConfig->enumerate(translatedKey, range); +} + + +void ConfigurationView::removeRaw(const std::string& key) +{ + std::string translatedKey = translateKey(key); + _pConfig->remove(translatedKey); +} + + +std::string ConfigurationView::translateKey(const std::string& key) const +{ + std::string result = _prefix; + if (!result.empty() && !key.empty() && key[0] != '[') result += '.'; + result += key; + return result; +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/FilesystemConfiguration.cpp b/contrib/libs/poco/Util/src/FilesystemConfiguration.cpp new file mode 100644 index 0000000000..1978694a37 --- /dev/null +++ b/contrib/libs/poco/Util/src/FilesystemConfiguration.cpp @@ -0,0 +1,127 @@ +// +// FilesystemConfiguration.cpp +// +// Library: Util +// Package: Configuration +// Module: FilesystemConfiguration +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/FilesystemConfiguration.h" +#include "Poco/File.h" +#include "Poco/Path.h" +#include "Poco/DirectoryIterator.h" +#include "Poco/StringTokenizer.h" +#include "Poco/FileStream.h" + + +using Poco::Path; +using Poco::File; +using Poco::DirectoryIterator; +using Poco::StringTokenizer; + + +namespace Poco { +namespace Util { + + +FilesystemConfiguration::FilesystemConfiguration(const std::string& path): + _path(path) +{ + _path.makeDirectory(); +} + + +FilesystemConfiguration::~FilesystemConfiguration() +{ +} + + +void FilesystemConfiguration::clear() +{ + File regDir(_path); + regDir.remove(true); +} + + +bool FilesystemConfiguration::getRaw(const std::string& key, std::string& value) const +{ + Path p(keyToPath(key)); + p.setFileName("data"); + File f(p); + if (f.exists()) + { + value.reserve((std::string::size_type) f.getSize()); + Poco::FileInputStream istr(p.toString()); + int c = istr.get(); + while (c != std::char_traits<char>::eof()) + { + value += (char) c; + c = istr.get(); + } + return true; + } + else return false; +} + + +void FilesystemConfiguration::setRaw(const std::string& key, const std::string& value) +{ + Path p(keyToPath(key)); + File dir(p); + dir.createDirectories(); + p.setFileName("data"); + Poco::FileOutputStream ostr(p.toString()); + ostr.write(value.data(), (std::streamsize) value.length()); +} + + +void FilesystemConfiguration::enumerate(const std::string& key, Keys& range) const +{ + Path p(keyToPath(key)); + File dir(p); + if (!dir.exists()) + { + return; + } + + DirectoryIterator it(p); + DirectoryIterator end; + while (it != end) + { + if (it->isDirectory()) + range.push_back(it.name()); + ++it; + } +} + + +void FilesystemConfiguration::removeRaw(const std::string& key) +{ + Path p(keyToPath(key)); + File dir(p); + if (dir.exists()) + { + dir.remove(true); + } +} + + +Path FilesystemConfiguration::keyToPath(const std::string& key) const +{ + Path result(_path); + StringTokenizer tokenizer(key, ".", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + for (StringTokenizer::Iterator it = tokenizer.begin(); it != tokenizer.end(); ++it) + { + result.pushDirectory(*it); + } + return result; +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/HelpFormatter.cpp b/contrib/libs/poco/Util/src/HelpFormatter.cpp new file mode 100644 index 0000000000..41c8d28720 --- /dev/null +++ b/contrib/libs/poco/Util/src/HelpFormatter.cpp @@ -0,0 +1,296 @@ +// +// HelpFormatter.cpp +// +// Library: Util +// Package: Options +// Module: HelpFormatter +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/HelpFormatter.h" +#include "Poco/Util/OptionSet.h" +#include "Poco/Util/Option.h" + + +namespace Poco { +namespace Util { + + +const int HelpFormatter::TAB_WIDTH = 4; +const int HelpFormatter::LINE_WIDTH = 78; + + +HelpFormatter::HelpFormatter(const OptionSet& options): + _options(options), + _width(LINE_WIDTH), + _indent(0), + _unixStyle(true) +{ +#if !defined(POCO_OS_FAMILY_UNIX) + _unixStyle = false; +#endif + _indent = calcIndent(); +} + + +HelpFormatter::~HelpFormatter() +{ +} + + +void HelpFormatter::setCommand(const std::string& command) +{ + _command = command; +} + + +void HelpFormatter::setUsage(const std::string& usage) +{ + _usage = usage; +} + + +void HelpFormatter::setHeader(const std::string& header) +{ + _header = header; +} + + +void HelpFormatter::setFooter(const std::string& footer) +{ + _footer = footer; +} + + +void HelpFormatter::format(std::ostream& ostr) const +{ + ostr << "usage: " << _command; + if (!_usage.empty()) + { + ostr << ' '; + formatText(ostr, _usage, (int) _command.length() + 1); + } + ostr << '\n'; + if (!_header.empty()) + { + formatText(ostr, _header, 0); + ostr << "\n\n"; + } + formatOptions(ostr); + if (!_footer.empty()) + { + ostr << '\n'; + formatText(ostr, _footer, 0); + ostr << '\n'; + } +} + + +void HelpFormatter::setWidth(int width) +{ + poco_assert (width > 0); + + _width = width; +} + + +void HelpFormatter::setIndent(int indent) +{ + poco_assert (indent >= 0 && indent < _width); + + _indent = indent; +} + + +void HelpFormatter::setAutoIndent() +{ + _indent = calcIndent(); +} + + +void HelpFormatter::setUnixStyle(bool flag) +{ + _unixStyle = flag; +} + + +int HelpFormatter::calcIndent() const +{ + int indent = 0; + for (OptionSet::Iterator it = _options.begin(); it != _options.end(); ++it) + { + int shortLen = (int) it->shortName().length(); + int fullLen = (int) it->fullName().length(); + int n = 0; + if (_unixStyle && shortLen > 0) + { + n += shortLen + (int) shortPrefix().length(); + if (it->takesArgument()) + n += (int) it->argumentName().length() + (it->argumentRequired() ? 0 : 2); + if (fullLen > 0) n += 2; + } + if (fullLen > 0) + { + n += fullLen + (int) longPrefix().length(); + if (it->takesArgument()) + n += 1 + (int) it->argumentName().length() + (it->argumentRequired() ? 0 : 2); + } + n += 2; + if (n > indent) + indent = n; + } + return indent; +} + + +void HelpFormatter::formatOptions(std::ostream& ostr) const +{ + int optWidth = calcIndent(); + for (OptionSet::Iterator it = _options.begin(); it != _options.end(); ++it) + { + formatOption(ostr, *it, optWidth); + if (_indent < optWidth) + { + ostr << '\n' << std::string(_indent, ' '); + formatText(ostr, it->description(), _indent, _indent); + } + else + { + formatText(ostr, it->description(), _indent, optWidth); + } + ostr << '\n'; + } +} + + +void HelpFormatter::formatOption(std::ostream& ostr, const Option& option, int width) const +{ + int shortLen = (int) option.shortName().length(); + int fullLen = (int) option.fullName().length(); + + int n = 0; + if (_unixStyle && shortLen > 0) + { + ostr << shortPrefix() << option.shortName(); + n += (int) shortPrefix().length() + (int) option.shortName().length(); + if (option.takesArgument()) + { + if (!option.argumentRequired()) { ostr << '['; ++n; } + ostr << option.argumentName(); + n += (int) option.argumentName().length(); + if (!option.argumentRequired()) { ostr << ']'; ++n; } + } + if (fullLen > 0) { ostr << ", "; n += 2; } + } + if (fullLen > 0) + { + ostr << longPrefix() << option.fullName(); + n += (int) longPrefix().length() + (int) option.fullName().length(); + if (option.takesArgument()) + { + if (!option.argumentRequired()) { ostr << '['; ++n; } + ostr << '='; + ++n; + ostr << option.argumentName(); + n += (int) option.argumentName().length(); + if (!option.argumentRequired()) { ostr << ']'; ++n; } + } + } + while (n < width) { ostr << ' '; ++n; } +} + + +void HelpFormatter::formatText(std::ostream& ostr, const std::string& text, int indent) const +{ + formatText(ostr, text, indent, indent); +} + + +void HelpFormatter::formatText(std::ostream& ostr, const std::string& text, int indent, int firstIndent) const +{ + int pos = firstIndent; + int maxWordLen = _width - indent; + std::string word; + for (std::string::const_iterator it = text.begin(); it != text.end(); ++it) + { + if (*it == '\n') + { + clearWord(ostr, pos, word, indent); + ostr << '\n'; + pos = 0; + while (pos < indent) { ostr << ' '; ++pos; } + } + else if (*it == '\t') + { + clearWord(ostr, pos, word, indent); + if (pos < _width) ++pos; + while (pos < _width && pos % TAB_WIDTH != 0) + { + ostr << ' '; + ++pos; + } + } + else if (*it == ' ') + { + clearWord(ostr, pos, word, indent); + if (pos < _width) { ostr << ' '; ++pos; } + } + else + { + if (word.length() == maxWordLen) + { + clearWord(ostr, pos, word, indent); + } + else word += *it; + } + } + clearWord(ostr, pos, word, indent); +} + + +void HelpFormatter::formatWord(std::ostream& ostr, int& pos, const std::string& word, int indent) const +{ + if (pos + word.length() > _width) + { + ostr << '\n'; + pos = 0; + while (pos < indent) { ostr << ' '; ++pos; } + } + ostr << word; + pos += (int) word.length(); +} + + +void HelpFormatter::clearWord(std::ostream& ostr, int& pos, std::string& word, int indent) const +{ + formatWord(ostr, pos, word, indent); + word.clear(); +} + + +std::string HelpFormatter::shortPrefix() const +{ +#if defined(POCO_OS_FAMILY_UNIX) + return "-"; +#else + return _unixStyle ? "-" : "/"; +#endif +} + + +std::string HelpFormatter::longPrefix() const +{ +#if defined(POCO_OS_FAMILY_UNIX) + return "--"; +#else + return _unixStyle ? "--" : "/"; +#endif +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/IniFileConfiguration.cpp b/contrib/libs/poco/Util/src/IniFileConfiguration.cpp new file mode 100644 index 0000000000..76447c10ab --- /dev/null +++ b/contrib/libs/poco/Util/src/IniFileConfiguration.cpp @@ -0,0 +1,190 @@ +// +// IniFileConfiguration.cpp +// +// Library: Util +// Package: Configuration +// Module: IniFileConfiguration +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/IniFileConfiguration.h" + + +#ifndef POCO_UTIL_NO_INIFILECONFIGURATION + + +#include "Poco/Exception.h" +#include "Poco/String.h" +#include "Poco/Path.h" +#include "Poco/FileStream.h" +#include "Poco/Ascii.h" +#include <set> + + +using Poco::icompare; +using Poco::trim; +using Poco::Path; + + +namespace Poco { +namespace Util { + + +IniFileConfiguration::IniFileConfiguration() +{ +} + + +IniFileConfiguration::IniFileConfiguration(std::istream& istr) +{ + load(istr); +} + + +IniFileConfiguration::IniFileConfiguration(const std::string& path) +{ + load(path); +} + + +IniFileConfiguration::~IniFileConfiguration() +{ +} + + +void IniFileConfiguration::load(std::istream& istr) +{ + _map.clear(); + _sectionKey.clear(); + while (!istr.eof()) + { + parseLine(istr); + } +} + + +void IniFileConfiguration::load(const std::string& path) +{ + Poco::FileInputStream istr(path); + if (istr.good()) + load(istr); + else + throw Poco::OpenFileException(path); +} + + +bool IniFileConfiguration::getRaw(const std::string& key, std::string& value) const +{ + IStringMap::const_iterator it = _map.find(key); + if (it != _map.end()) + { + value = it->second; + return true; + } + else return false; +} + + +void IniFileConfiguration::setRaw(const std::string& key, const std::string& value) +{ + _map[key] = value; +} + + +void IniFileConfiguration::enumerate(const std::string& key, Keys& range) const +{ + std::set<std::string> keys; + std::string prefix = key; + if (!prefix.empty()) prefix += '.'; + std::string::size_type psize = prefix.size(); + for (IStringMap::const_iterator it = _map.begin(); it != _map.end(); ++it) + { + if (icompare(it->first, psize, prefix) == 0) + { + std::string subKey; + std::string::size_type end = it->first.find('.', psize); + if (end == std::string::npos) + subKey = it->first.substr(psize); + else + subKey = it->first.substr(psize, end - psize); + if (keys.find(subKey) == keys.end()) + { + range.push_back(subKey); + keys.insert(subKey); + } + } + } +} + + +void IniFileConfiguration::removeRaw(const std::string& key) +{ + std::string prefix = key; + if (!prefix.empty()) prefix += '.'; + std::string::size_type psize = prefix.size(); + IStringMap::iterator it = _map.begin(); + IStringMap::iterator itCur; + while (it != _map.end()) + { + itCur = it++; + if ((icompare(itCur->first, key) == 0) || (icompare(itCur->first, psize, prefix) == 0)) + { + _map.erase(itCur); + } + } +} + + +bool IniFileConfiguration::ICompare::operator () (const std::string& s1, const std::string& s2) const +{ + return icompare(s1, s2) < 0; +} + + +void IniFileConfiguration::parseLine(std::istream& istr) +{ + static const int eof = std::char_traits<char>::eof(); + + int c = istr.get(); + while (c != eof && Poco::Ascii::isSpace(c)) c = istr.get(); + if (c != eof) + { + if (c == ';') + { + while (c != eof && c != '\n') c = istr.get(); + } + else if (c == '[') + { + std::string key; + c = istr.get(); + while (c != eof && c != ']' && c != '\n') { key += (char) c; c = istr.get(); } + _sectionKey = trim(key); + } + else + { + std::string key; + while (c != eof && c != '=' && c != '\n') { key += (char) c; c = istr.get(); } + std::string value; + if (c == '=') + { + c = istr.get(); + while (c != eof && c != '\n') { value += (char) c; c = istr.get(); } + } + std::string fullKey = _sectionKey; + if (!fullKey.empty()) fullKey += '.'; + fullKey.append(trim(key)); + _map[fullKey] = trim(value); + } + } +} + + +} } // namespace Poco::Util + + +#endif // POCO_UTIL_NO_INIFILECONFIGURATION
\ No newline at end of file diff --git a/contrib/libs/poco/Util/src/IntValidator.cpp b/contrib/libs/poco/Util/src/IntValidator.cpp new file mode 100644 index 0000000000..e5372ee098 --- /dev/null +++ b/contrib/libs/poco/Util/src/IntValidator.cpp @@ -0,0 +1,54 @@ +// +// IntValidator.cpp +// +// Library: Util +// Package: Options +// Module: IntValidator +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/IntValidator.h" +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionException.h" +#include "Poco/NumberParser.h" +#include "Poco/Format.h" + + +using Poco::NumberParser; +using Poco::format; + + +namespace Poco { +namespace Util { + + +IntValidator::IntValidator(int min, int max): + _min(min), + _max(max) +{ +} + + +IntValidator::~IntValidator() +{ +} + + +void IntValidator::validate(const Option& option, const std::string& value) +{ + int n; + if (NumberParser::tryParse(value, n)) + { + if (n < _min || n > _max) + throw InvalidArgumentException(format("argument for %s must be in range %d to %d", option.fullName(), _min, _max)); + } + else throw InvalidArgumentException(format("argument for %s must be an integer", option.fullName())); +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/JSONConfiguration.cpp b/contrib/libs/poco/Util/src/JSONConfiguration.cpp new file mode 100644 index 0000000000..282ac8ce5e --- /dev/null +++ b/contrib/libs/poco/Util/src/JSONConfiguration.cpp @@ -0,0 +1,386 @@ +// +// JSONConfiguration.cpp +// +// Library: Util +// Package: JSON +// Module: JSONConfiguration +// +// Copyright (c) 2012, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + + +#include "Poco/Util/JSONConfiguration.h" + + +#ifndef POCO_UTIL_NO_JSONCONFIGURATION + + +#include "Poco/FileStream.h" +#include "Poco/StringTokenizer.h" +#include "Poco/JSON/Parser.h" +#include "Poco/JSON/Query.h" +#include "Poco/RegularExpression.h" +#include "Poco/NumberParser.h" + + +namespace Poco { +namespace Util { + + +JSONConfiguration::JSONConfiguration() : _object(new JSON::Object()) +{ +} + + +JSONConfiguration::JSONConfiguration(const std::string& path) +{ + load(path); +} + + +JSONConfiguration::JSONConfiguration(std::istream& istr) +{ + load(istr); +} + + +JSONConfiguration::JSONConfiguration(const JSON::Object::Ptr& object) : _object(object) +{ +} + + +JSONConfiguration::~JSONConfiguration() +{ +} + + +void JSONConfiguration::load(const std::string& path) +{ + Poco::FileInputStream fis(path); + load(fis); +} + + +void JSONConfiguration::load(std::istream& istr) +{ + JSON::Parser parser; + parser.parse(istr); + DynamicAny result = parser.result(); + if ( result.type() == typeid(JSON::Object::Ptr) ) + { + _object = result.extract<JSON::Object::Ptr>(); + } +} + + +void JSONConfiguration::loadEmpty(const std::string& root) +{ + _object = new JSON::Object(); + JSON::Object::Ptr rootObject = new JSON::Object(); + _object->set(root, rootObject); +} + + +bool JSONConfiguration::getRaw(const std::string & key, std::string & value) const +{ + JSON::Query query(_object); + Poco::DynamicAny result = query.find(key); + if ( ! result.isEmpty() ) + { + value = result.convert<std::string>(); + return true; + } + return false; +} + + +void JSONConfiguration::getIndexes(std::string& name, std::vector<int>& indexes) +{ + indexes.clear(); + + RegularExpression::MatchVec matches; + int firstOffset = -1; + int offset = 0; + RegularExpression regex("\\[([0-9]+)\\]"); + while(regex.match(name, offset, matches) > 0 ) + { + if ( firstOffset == -1 ) + { + firstOffset = static_cast<int>(matches[0].offset); + } + std::string num = name.substr(matches[1].offset, matches[1].length); + indexes.push_back(NumberParser::parse(num)); + offset = static_cast<int>(matches[0].offset + matches[0].length); + } + + if ( firstOffset != -1 ) + { + name = name.substr(0, firstOffset); + } +} + + +JSON::Object::Ptr JSONConfiguration::findStart(const std::string& key, std::string& lastPart) +{ + JSON::Object::Ptr currentObject = _object; + + StringTokenizer tokenizer(key, "."); + lastPart = tokenizer[tokenizer.count() - 1]; + + for(int i = 0; i < tokenizer.count() - 1; ++i) + { + std::vector<int> indexes; + std::string name = tokenizer[i]; + getIndexes(name, indexes); + + DynamicAny result = currentObject->get(name); + + if ( result.isEmpty() ) // Not found + { + if ( indexes.empty() ) // We want an object, create it + { + JSON::Object::Ptr newObject = new JSON::Object(); + currentObject->set(name, newObject); + currentObject = newObject; + } + else // We need an array + { + JSON::Array::Ptr newArray; + JSON::Array::Ptr parentArray; + JSON::Array::Ptr topArray; + for(std::vector<int>::iterator it = indexes.begin(); it != indexes.end(); ++it) + { + newArray = new JSON::Array(); + if ( topArray.isNull() ) + { + topArray = newArray; + } + + if ( ! parentArray.isNull() ) + { + parentArray->add(newArray); + } + + for(int i = 0; i <= *it - 1; ++i) + { + Poco::DynamicAny nullValue; + newArray->add(nullValue); + } + + parentArray = newArray; + } + + currentObject->set(name, topArray); + currentObject = new JSON::Object(); + newArray->add(currentObject); + } + } + else // We have a value + { + if ( indexes.empty() ) // We want an object + { + if ( result.type() == typeid(JSON::Object::Ptr) ) + { + currentObject = result.extract<JSON::Object::Ptr>(); + } + else + { + throw SyntaxException("Expected a JSON object"); + } + } + else + { + if ( result.type() == typeid(JSON::Array::Ptr) ) + { + JSON::Array::Ptr arr = result.extract<JSON::Array::Ptr>(); + + for(std::vector<int>::iterator it = indexes.begin(); it != indexes.end() - 1; ++it) + { + JSON::Array::Ptr currentArray = arr; + arr = arr->getArray(*it); + if ( arr.isNull() ) + { + arr = new JSON::Array(); + currentArray->add(arr); + } + } + + result = arr->get(*indexes.rbegin()); + if ( result.isEmpty() ) // Index doesn't exist + { + JSON::Object::Ptr newObject = new JSON::Object(); + arr->add(newObject); + currentObject = newObject; + } + else // Index is available + { + if ( result.type() == typeid(JSON::Object::Ptr) ) + { + currentObject = result.extract<JSON::Object::Ptr>(); + } + else + { + throw SyntaxException("Expected a JSON object"); + } + } + } + else + { + throw SyntaxException("Expected a JSON array"); + } + } + } + } + return currentObject; +} + + +void JSONConfiguration::setValue(const std::string& key, const Poco::DynamicAny& value) +{ + + std::string sValue; + + value.convert<std::string>(sValue); + KeyValue kv(key, sValue); + + if (eventsEnabled()) + { + propertyChanging(this, kv); + } + + std::string lastPart; + JSON::Object::Ptr parentObject = findStart(key, lastPart); + + std::vector<int> indexes; + getIndexes(lastPart, indexes); + + if ( indexes.empty() ) // No Array + { + parentObject->set(lastPart, value); + } + else + { + DynamicAny result = parentObject->get(lastPart); + if ( result.isEmpty() ) + { + result = JSON::Array::Ptr(new JSON::Array()); + parentObject->set(lastPart, result); + } + else if ( result.type() != typeid(JSON::Array::Ptr) ) + { + throw SyntaxException("Expected a JSON array"); + } + + JSON::Array::Ptr arr = result.extract<JSON::Array::Ptr>(); + for(std::vector<int>::iterator it = indexes.begin(); it != indexes.end() - 1; ++it) + { + JSON::Array::Ptr nextArray = arr->getArray(*it); + if ( nextArray.isNull() ) + { + for(int i = static_cast<int>(arr->size()); i <= *it; ++i) + { + Poco::DynamicAny nullValue; + arr->add(nullValue); + } + nextArray = new JSON::Array(); + arr->add(nextArray); + } + arr = nextArray; + } + arr->set(indexes.back(), value); + } + + if (eventsEnabled()) + { + propertyChanged(this, kv); + } +} + + +void JSONConfiguration::setString(const std::string& key, const std::string& value) +{ + setValue(key, value); +} + + +void JSONConfiguration::setRaw(const std::string& key, const std::string& value) +{ + setValue(key, value); +} + + +void JSONConfiguration::setInt(const std::string& key, int value) +{ + setValue(key, value); +} + + +void JSONConfiguration::setBool(const std::string& key, bool value) +{ + setValue(key, value); +} + + +void JSONConfiguration::setDouble(const std::string& key, double value) +{ + setValue(key, value); +} + + +void JSONConfiguration::enumerate(const std::string& key, Keys& range) const +{ + JSON::Query query(_object); + Poco::DynamicAny result = query.find(key); + if ( result.type() == typeid(JSON::Object::Ptr) ) + { + JSON::Object::Ptr object = result.extract<JSON::Object::Ptr>(); + object->getNames(range); + } +} + + +void JSONConfiguration::save(std::ostream& ostr, unsigned int indent) const +{ + _object->stringify(ostr, indent); +} + + +void JSONConfiguration::removeRaw(const std::string& key) + +{ + + std::string lastPart; + JSON::Object::Ptr parentObject = findStart(key, lastPart); + std::vector<int> indexes; + getIndexes(lastPart, indexes); + + if ( indexes.empty() ) // No Array + { + parentObject->remove(lastPart); + } + else + { + DynamicAny result = parentObject->get(lastPart); + if (!result.isEmpty() && result.type() == typeid(JSON::Array::Ptr)) + { + + JSON::Array::Ptr arr = result.extract<JSON::Array::Ptr>(); + for(std::vector<int>::iterator it = indexes.begin(); it != indexes.end() - 1; ++it) + { + arr = arr->getArray(*it); + } + arr->remove(indexes.back()); + } + } + +} + + +} } // namespace Poco::Util + + +#endif // POCO_UTIL_NO_JSONCONFIGURATION diff --git a/contrib/libs/poco/Util/src/LayeredConfiguration.cpp b/contrib/libs/poco/Util/src/LayeredConfiguration.cpp new file mode 100644 index 0000000000..1cbd5d7847 --- /dev/null +++ b/contrib/libs/poco/Util/src/LayeredConfiguration.cpp @@ -0,0 +1,233 @@ +// +// LayeredConfiguration.cpp +// +// Library: Util +// Package: Configuration +// Module: LayeredConfiguration +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/LayeredConfiguration.h" +#include "Poco/Exception.h" +#include <set> + + +using Poco::AutoPtr; +using Poco::RuntimeException; + + +namespace Poco { +namespace Util { + + +LayeredConfiguration::LayeredConfiguration() +{ +} + + +LayeredConfiguration::~LayeredConfiguration() +{ +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig) +{ + add(pConfig, highest(), false, true); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, const std::string& label) +{ + add(pConfig, label, highest(), false, true); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, bool shared) +{ + add(pConfig, highest(), false, shared); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, const std::string& label, bool shared) +{ + add(pConfig, label, highest(), false, shared); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, int priority) +{ + add(pConfig, priority, false, true); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, const std::string& label, int priority) +{ + add(pConfig, label, priority, false, true); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, int priority, bool shared) +{ + add(pConfig, priority, false, shared); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, const std::string& label, int priority, bool shared) +{ + add(pConfig, label, priority, false, shared); +} + + +void LayeredConfiguration::addFront(AbstractConfiguration* pConfig) +{ + add(pConfig, lowest(), false, true); +} + + +void LayeredConfiguration::addFront(AbstractConfiguration* pConfig, bool shared) +{ + add(pConfig, lowest(), false, shared); +} + + +void LayeredConfiguration::addWriteable(AbstractConfiguration* pConfig, int priority) +{ + add(pConfig, priority, true, true); +} + + +void LayeredConfiguration::addWriteable(AbstractConfiguration* pConfig, int priority, bool shared) +{ + add(pConfig, priority, true, shared); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, int priority, bool writeable, bool shared) +{ + add(pConfig, std::string(), priority, writeable, shared); +} + + +void LayeredConfiguration::add(AbstractConfiguration* pConfig, const std::string& label, int priority, bool writeable, bool shared) +{ + ConfigItem item; + item.pConfig = ConfigPtr(pConfig, shared); + item.priority = priority; + item.writeable = writeable; + item.label = label; + + ConfigList::iterator it = _configs.begin(); + while (it != _configs.end() && it->priority < priority) + ++it; + + _configs.insert(it, item); +} + + +void LayeredConfiguration::removeConfiguration(AbstractConfiguration* pConfig) +{ + for (ConfigList::iterator it = _configs.begin(); it != _configs.end(); ++it) + { + if (it->pConfig == pConfig) + { + _configs.erase(it); + break; + } + } +} + + +LayeredConfiguration::ConfigPtr LayeredConfiguration::find(const std::string& label) const +{ + for (ConfigList::const_iterator it = _configs.begin(); it != _configs.end(); ++it) + { + if (it->label == label) + { + return it->pConfig; + } + } + return 0; +} + + +bool LayeredConfiguration::getRaw(const std::string& key, std::string& value) const +{ + for (ConfigList::const_iterator it = _configs.begin(); it != _configs.end(); ++it) + { + if (it->pConfig->getRaw(key, value)) + return true; + } + return false; +} + + +void LayeredConfiguration::setRaw(const std::string& key, const std::string& value) +{ + for (ConfigList::iterator it = _configs.begin(); it != _configs.end(); ++it) + { + if (it->writeable) + { + it->pConfig->setRaw(key, value); + return; + } + } + throw RuntimeException("No writeable configuration object to store the property", key); +} + + +void LayeredConfiguration::enumerate(const std::string& key, Keys& range) const +{ + std::set<std::string> keys; + for (ConfigList::const_iterator itc = _configs.begin(); itc != _configs.end(); ++itc) + { + Keys partRange; + itc->pConfig->enumerate(key, partRange); + for (Keys::const_iterator itr = partRange.begin(); itr != partRange.end(); ++itr) + { + if (keys.find(*itr) == keys.end()) + { + range.push_back(*itr); + keys.insert(*itr); + } + } + } +} + + +void LayeredConfiguration::removeRaw(const std::string& key) +{ + for (ConfigList::iterator it = _configs.begin(); it != _configs.end(); ++it) + { + if (it->writeable) + { + it->pConfig->remove(key); + return; + } + } +} + + +int LayeredConfiguration::lowest() const +{ + if (_configs.empty()) + return 0; + else + return _configs.front().priority - 1; +} + + +int LayeredConfiguration::highest() const +{ + if (_configs.empty()) + return 0; + else + return _configs.back().priority + 1; +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/LoggingConfigurator.cpp b/contrib/libs/poco/Util/src/LoggingConfigurator.cpp new file mode 100644 index 0000000000..82b9d7d331 --- /dev/null +++ b/contrib/libs/poco/Util/src/LoggingConfigurator.cpp @@ -0,0 +1,203 @@ +// +// LoggingConfigurator.cpp +// +// Library: Util +// Package: Configuration +// Module: LoggingConfigurator +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/LoggingConfigurator.h" +#include "Poco/Util/AbstractConfiguration.h" +#include "Poco/AutoPtr.h" +#include "Poco/Channel.h" +#include "Poco/FormattingChannel.h" +#include "Poco/Formatter.h" +#include "Poco/PatternFormatter.h" +#include "Poco/Logger.h" +#include "Poco/LoggingRegistry.h" +#include "Poco/LoggingFactory.h" +#include <map> + + +using Poco::AutoPtr; +using Poco::Formatter; +using Poco::PatternFormatter; +using Poco::Channel; +using Poco::FormattingChannel; +using Poco::Logger; +using Poco::LoggingRegistry; +using Poco::LoggingFactory; + + +namespace Poco { +namespace Util { + + +LoggingConfigurator::LoggingConfigurator() +{ +} + + +LoggingConfigurator::~LoggingConfigurator() +{ +} + + +void LoggingConfigurator::configure(AbstractConfiguration* pConfig) +{ + poco_check_ptr (pConfig); + + AutoPtr<AbstractConfiguration> pFormattersConfig(pConfig->createView("logging.formatters")); + configureFormatters(pFormattersConfig); + + AutoPtr<AbstractConfiguration> pChannelsConfig(pConfig->createView("logging.channels")); + configureChannels(pChannelsConfig); + + AutoPtr<AbstractConfiguration> pLoggersConfig(pConfig->createView("logging.loggers")); + configureLoggers(pLoggersConfig); +} + + +void LoggingConfigurator::configureFormatters(AbstractConfiguration* pConfig) +{ + AbstractConfiguration::Keys formatters; + pConfig->keys(formatters); + for (AbstractConfiguration::Keys::const_iterator it = formatters.begin(); it != formatters.end(); ++it) + { + AutoPtr<AbstractConfiguration> pFormatterConfig(pConfig->createView(*it)); + AutoPtr<Formatter> pFormatter(createFormatter(pFormatterConfig)); + LoggingRegistry::defaultRegistry().registerFormatter(*it, pFormatter); + } +} + + +void LoggingConfigurator::configureChannels(AbstractConfiguration* pConfig) +{ + AbstractConfiguration::Keys channels; + pConfig->keys(channels); + for (AbstractConfiguration::Keys::const_iterator it = channels.begin(); it != channels.end(); ++it) + { + AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(*it)); + AutoPtr<Channel> pChannel = createChannel(pChannelConfig); + LoggingRegistry::defaultRegistry().registerChannel(*it, pChannel); + } + for (AbstractConfiguration::Keys::const_iterator it = channels.begin(); it != channels.end(); ++it) + { + AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(*it)); + Channel* pChannel = LoggingRegistry::defaultRegistry().channelForName(*it); + configureChannel(pChannel, pChannelConfig); + } +} + + +void LoggingConfigurator::configureLoggers(AbstractConfiguration* pConfig) +{ + typedef std::map<std::string, AutoPtr<AbstractConfiguration> > LoggerMap; + + AbstractConfiguration::Keys loggers; + pConfig->keys(loggers); + // use a map to sort loggers by their name, ensuring initialization in correct order (parents before children) + LoggerMap loggerMap; + for (AbstractConfiguration::Keys::const_iterator it = loggers.begin(); it != loggers.end(); ++it) + { + AutoPtr<AbstractConfiguration> pLoggerConfig(pConfig->createView(*it)); + loggerMap[pLoggerConfig->getString("name", "")] = pLoggerConfig; + } + for (LoggerMap::iterator it = loggerMap.begin(); it != loggerMap.end(); ++it) + { + configureLogger(it->second); + } +} + + +Formatter* LoggingConfigurator::createFormatter(AbstractConfiguration* pConfig) +{ + AutoPtr<Formatter> pFormatter(LoggingFactory::defaultFactory().createFormatter(pConfig->getString("class"))); + AbstractConfiguration::Keys props; + pConfig->keys(props); + for (AbstractConfiguration::Keys::const_iterator it = props.begin(); it != props.end(); ++it) + { + if (*it != "class") + pFormatter->setProperty(*it, pConfig->getString(*it)); + } + return pFormatter.duplicate(); +} + + +Channel* LoggingConfigurator::createChannel(AbstractConfiguration* pConfig) +{ + AutoPtr<Channel> pChannel(LoggingFactory::defaultFactory().createChannel(pConfig->getString("class"))); + AutoPtr<Channel> pWrapper(pChannel); + AbstractConfiguration::Keys props; + pConfig->keys(props); + for (AbstractConfiguration::Keys::const_iterator it = props.begin(); it != props.end(); ++it) + { + if (*it == "pattern") + { + AutoPtr<Formatter> pPatternFormatter(new PatternFormatter(pConfig->getString(*it))); + pWrapper = new FormattingChannel(pPatternFormatter, pChannel); + } + else if (*it == "formatter") + { + AutoPtr<FormattingChannel> pFormattingChannel(new FormattingChannel(0, pChannel)); + if (pConfig->hasProperty("formatter.class")) + { + AutoPtr<AbstractConfiguration> pFormatterConfig(pConfig->createView(*it)); + AutoPtr<Formatter> pFormatter(createFormatter(pFormatterConfig)); + pFormattingChannel->setFormatter(pFormatter); + } + else pFormattingChannel->setProperty(*it, pConfig->getString(*it)); +#if defined(__GNUC__) && __GNUC__ < 3 + pWrapper = pFormattingChannel.duplicate(); +#else + pWrapper = pFormattingChannel; +#endif + } + } + return pWrapper.duplicate(); +} + + +void LoggingConfigurator::configureChannel(Channel* pChannel, AbstractConfiguration* pConfig) +{ + AbstractConfiguration::Keys props; + pConfig->keys(props); + for (AbstractConfiguration::Keys::const_iterator it = props.begin(); it != props.end(); ++it) + { + if (*it != "pattern" && *it != "formatter" && *it != "class") + { + pChannel->setProperty(*it, pConfig->getString(*it)); + } + } +} + + +void LoggingConfigurator::configureLogger(AbstractConfiguration* pConfig) +{ + Logger& logger = Logger::get(pConfig->getString("name", "")); + AbstractConfiguration::Keys props; + pConfig->keys(props); + for (AbstractConfiguration::Keys::const_iterator it = props.begin(); it != props.end(); ++it) + { + if (*it == "channel" && pConfig->hasProperty("channel.class")) + { + AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(*it)); + AutoPtr<Channel> pChannel(createChannel(pChannelConfig)); + configureChannel(pChannel, pChannelConfig); + Logger::setChannel(logger.name(), pChannel); + } + else if (*it != "name") + { + Logger::setProperty(logger.name(), *it, pConfig->getString(*it)); + } + } +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/LoggingSubsystem.cpp b/contrib/libs/poco/Util/src/LoggingSubsystem.cpp new file mode 100644 index 0000000000..08d51a32e1 --- /dev/null +++ b/contrib/libs/poco/Util/src/LoggingSubsystem.cpp @@ -0,0 +1,58 @@ +// +// LoggingSubsystem.cpp +// +// Library: Util +// Package: Application +// Module: LoggingSubsystem +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/LoggingSubsystem.h" +#include "Poco/Util/LoggingConfigurator.h" +#include "Poco/Util/Application.h" +#include "Poco/Logger.h" + + +using Poco::Logger; + + +namespace Poco { +namespace Util { + + +LoggingSubsystem::LoggingSubsystem() +{ +} + + +LoggingSubsystem::~LoggingSubsystem() +{ +} + + +const char* LoggingSubsystem::name() const +{ + return "Logging Subsystem"; +} + + +void LoggingSubsystem::initialize(Application& app) +{ + LoggingConfigurator configurator; + configurator.configure(&app.config()); + std::string logger = app.config().getString("application.logger", "Application"); + app.setLogger(Logger::get(logger)); +} + + +void LoggingSubsystem::uninitialize() +{ +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/MapConfiguration.cpp b/contrib/libs/poco/Util/src/MapConfiguration.cpp new file mode 100644 index 0000000000..480956ba36 --- /dev/null +++ b/contrib/libs/poco/Util/src/MapConfiguration.cpp @@ -0,0 +1,122 @@ +// +// MapConfiguration.cpp +// +// Library: Util +// Package: Configuration +// Module: MapConfiguration +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/MapConfiguration.h" +#include <set> + + +namespace Poco { +namespace Util { + + +MapConfiguration::MapConfiguration() +{ +} + + +MapConfiguration::~MapConfiguration() +{ +} + + +void MapConfiguration::copyTo(AbstractConfiguration& config) +{ + for (iterator it = _map.begin(); it != _map.end(); ++it) + { + config.setString(it->first, it->second); + } +} + + +void MapConfiguration::clear() +{ + _map.clear(); +} + + +bool MapConfiguration::getRaw(const std::string& key, std::string& value) const +{ + StringMap::const_iterator it = _map.find(key); + if (it != _map.end()) + { + value = it->second; + return true; + } + else return false; +} + + +void MapConfiguration::setRaw(const std::string& key, const std::string& value) +{ + _map[key] = value; +} + + +void MapConfiguration::enumerate(const std::string& key, Keys& range) const +{ + std::set<std::string> keys; + std::string prefix = key; + if (!prefix.empty()) prefix += '.'; + std::string::size_type psize = prefix.size(); + for (StringMap::const_iterator it = _map.begin(); it != _map.end(); ++it) + { + if (it->first.compare(0, psize, prefix) == 0) + { + std::string subKey; + std::string::size_type end = it->first.find('.', psize); + if (end == std::string::npos) + subKey = it->first.substr(psize); + else + subKey = it->first.substr(psize, end - psize); + if (keys.find(subKey) == keys.end()) + { + range.push_back(subKey); + keys.insert(subKey); + } + } + } +} + + +void MapConfiguration::removeRaw(const std::string& key) +{ + std::string prefix = key; + if (!prefix.empty()) prefix += '.'; + std::string::size_type psize = prefix.size(); + StringMap::iterator it = _map.begin(); + StringMap::iterator itCur; + while (it != _map.end()) + { + itCur = it++; + if ((itCur->first == key) || (itCur->first.compare(0, psize, prefix) == 0)) + { + _map.erase(itCur); + } + } +} + + +MapConfiguration::iterator MapConfiguration::begin() const +{ + return _map.begin(); +} + + +MapConfiguration::iterator MapConfiguration::end() const +{ + return _map.end(); +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/Option.cpp b/contrib/libs/poco/Util/src/Option.cpp new file mode 100644 index 0000000000..cdf33ec067 --- /dev/null +++ b/contrib/libs/poco/Util/src/Option.cpp @@ -0,0 +1,292 @@ +// +// Option.cpp +// +// Library: Util +// Package: Options +// Module: Option +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionException.h" +#include "Poco/Util/Validator.h" +#include "Poco/Util/AbstractConfiguration.h" +#include "Poco/String.h" +#include <algorithm> + + +using Poco::icompare; + + +namespace Poco { +namespace Util { + + +Option::Option(): + _required(false), + _repeatable(false), + _argRequired(false), + _pValidator(0), + _pCallback(0), + _pConfig(0) +{ +} + + +Option::Option(const Option& option): + _shortName(option._shortName), + _fullName(option._fullName), + _description(option._description), + _required(option._required), + _repeatable(option._repeatable), + _argName(option._argName), + _argRequired(option._argRequired), + _group(option._group), + _binding(option._binding), + _pValidator(option._pValidator), + _pCallback(option._pCallback), + _pConfig(option._pConfig) +{ + if (_pValidator) _pValidator->duplicate(); + if (_pCallback) _pCallback = _pCallback->clone(); + if (_pConfig) _pConfig->duplicate(); +} + + +Option::Option(const std::string& fullName, const std::string& shortName): + _shortName(shortName), + _fullName(fullName), + _required(false), + _repeatable(false), + _argRequired(false), + _pValidator(0), + _pCallback(0), + _pConfig(0) +{ +} + + +Option::Option(const std::string& fullName, const std::string& shortName, const std::string& description, bool required): + _shortName(shortName), + _fullName(fullName), + _description(description), + _required(required), + _repeatable(false), + _argRequired(false), + _pValidator(0), + _pCallback(0), + _pConfig(0) +{ +} + + +Option::Option(const std::string& fullName, const std::string& shortName, const std::string& description, bool required, const std::string& argName, bool argRequired): + _shortName(shortName), + _fullName(fullName), + _description(description), + _required(required), + _repeatable(false), + _argName(argName), + _argRequired(argRequired), + _pValidator(0), + _pCallback(0), + _pConfig(0) +{ +} + + +Option::~Option() +{ + if (_pValidator) _pValidator->release(); + if (_pConfig) _pConfig->release(); + delete _pCallback; +} + + +Option& Option::operator = (const Option& option) +{ + if (&option != this) + { + Option tmp(option); + swap(tmp); + } + return *this; +} + + +void Option::swap(Option& option) +{ + std::swap(_shortName, option._shortName); + std::swap(_fullName, option._fullName); + std::swap(_description, option._description); + std::swap(_required, option._required); + std::swap(_repeatable, option._repeatable); + std::swap(_argName, option._argName); + std::swap(_argRequired, option._argRequired); + std::swap(_group, option._group); + std::swap(_binding, option._binding); + std::swap(_pValidator, option._pValidator); + std::swap(_pCallback, option._pCallback); + std::swap(_pConfig, option._pConfig); +} + + +Option& Option::shortName(const std::string& name) +{ + _shortName = name; + return *this; +} + + +Option& Option::fullName(const std::string& name) +{ + _fullName = name; + return *this; +} + + +Option& Option::description(const std::string& text) +{ + _description = text; + return *this; +} + + +Option& Option::required(bool flag) +{ + _required = flag; + return *this; +} + + +Option& Option::repeatable(bool flag) +{ + _repeatable = flag; + return *this; +} + + +Option& Option::argument(const std::string& name, bool required) +{ + _argName = name; + _argRequired = required; + return *this; +} + + +Option& Option::noArgument() +{ + _argName.clear(); + _argRequired = false; + return *this; +} + + +Option& Option::group(const std::string& group) +{ + _group = group; + return *this; +} + + +Option& Option::binding(const std::string& propertyName) +{ + return binding(propertyName, 0); +} + + +Option& Option::binding(const std::string& propertyName, AbstractConfiguration* pConfig) +{ + _binding = propertyName; + if (_pConfig) _pConfig->release(); + _pConfig = pConfig; + if (_pConfig) _pConfig->duplicate(); + return *this; +} + + +Option& Option::callback(const AbstractOptionCallback& cb) +{ + _pCallback = cb.clone(); + return *this; +} + + +Option& Option::validator(Validator* pValidator) +{ + if (_pValidator) _pValidator->release(); + _pValidator = pValidator; + return *this; +} + + +bool Option::matchesShort(const std::string& option) const +{ + return option.length() > 0 + && !_shortName.empty() && option.compare(0, _shortName.length(), _shortName) == 0; +} + + +bool Option::matchesFull(const std::string& option) const +{ + std::string::size_type pos = option.find_first_of(":="); + std::string::size_type len = pos == std::string::npos ? option.length() : pos; + return len == _fullName.length() + && icompare(option, 0, len, _fullName, 0, len) == 0; +} + + +bool Option::matchesPartial(const std::string& option) const +{ + std::string::size_type pos = option.find_first_of(":="); + std::string::size_type len = pos == std::string::npos ? option.length() : pos; + return option.length() > 0 + && icompare(option, 0, len, _fullName, 0, len) == 0; +} + + +void Option::process(const std::string& option, std::string& arg) const +{ + std::string::size_type pos = option.find_first_of(":="); + std::string::size_type len = pos == std::string::npos ? option.length() : pos; + if (icompare(option, 0, len, _fullName, 0, len) == 0) + { + if (takesArgument()) + { + if (argumentRequired() && pos == std::string::npos) + throw MissingArgumentException(_fullName + " requires " + argumentName()); + if (pos != std::string::npos) + arg.assign(option, pos + 1, option.length() - pos - 1); + else + arg.clear(); + } + else if (pos != std::string::npos) + { + throw UnexpectedArgumentException(option); + } + else arg.clear(); + } + else if (!_shortName.empty() && option.compare(0, _shortName.length(), _shortName) == 0) + { + if (takesArgument()) + { + if (argumentRequired() && option.length() == _shortName.length()) + throw MissingArgumentException(_shortName + " requires " + argumentName()); + arg.assign(option, _shortName.length(), option.length() - _shortName.length()); + } + else if (option.length() != _shortName.length()) + { + throw UnexpectedArgumentException(option); + } + else arg.clear(); + } + else throw UnknownOptionException(option); +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/OptionCallback.cpp b/contrib/libs/poco/Util/src/OptionCallback.cpp new file mode 100644 index 0000000000..f9fdfc33d0 --- /dev/null +++ b/contrib/libs/poco/Util/src/OptionCallback.cpp @@ -0,0 +1,37 @@ +// +// OptionCallback.cpp +// +// Library: Util +// Package: Options +// Module: OptionCallback +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/OptionCallback.h" + + +namespace Poco { +namespace Util { + + +AbstractOptionCallback::AbstractOptionCallback() +{ +} + + +AbstractOptionCallback::AbstractOptionCallback(const AbstractOptionCallback&) +{ +} + + +AbstractOptionCallback::~AbstractOptionCallback() +{ +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/OptionException.cpp b/contrib/libs/poco/Util/src/OptionException.cpp new file mode 100644 index 0000000000..cda4ed0b2d --- /dev/null +++ b/contrib/libs/poco/Util/src/OptionException.cpp @@ -0,0 +1,35 @@ +// +// OptionException.cpp +// +// Library: Util +// Package: Options +// Module: OptionException +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/OptionException.h" +#include <typeinfo> + + +namespace Poco { +namespace Util { + + +POCO_IMPLEMENT_EXCEPTION(OptionException, Poco::DataException, "Option exception") +POCO_IMPLEMENT_EXCEPTION(UnknownOptionException, OptionException, "Unknown option specified") +POCO_IMPLEMENT_EXCEPTION(AmbiguousOptionException, OptionException, "Ambiguous option specified") +POCO_IMPLEMENT_EXCEPTION(MissingOptionException, OptionException, "Required option not specified") +POCO_IMPLEMENT_EXCEPTION(MissingArgumentException, OptionException, "Missing option argument") +POCO_IMPLEMENT_EXCEPTION(InvalidArgumentException, OptionException, "Invalid option argument") +POCO_IMPLEMENT_EXCEPTION(UnexpectedArgumentException, OptionException, "Unexpected option argument") +POCO_IMPLEMENT_EXCEPTION(IncompatibleOptionsException, OptionException, "Incompatible options") +POCO_IMPLEMENT_EXCEPTION(DuplicateOptionException, OptionException, "Option must not be given more than once") +POCO_IMPLEMENT_EXCEPTION(EmptyOptionException, OptionException, "Empty option specified") + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/OptionProcessor.cpp b/contrib/libs/poco/Util/src/OptionProcessor.cpp new file mode 100644 index 0000000000..f9c3dc68da --- /dev/null +++ b/contrib/libs/poco/Util/src/OptionProcessor.cpp @@ -0,0 +1,159 @@ +// +// OptionProcessor.cpp +// +// Library: Util +// Package: Options +// Module: OptionProcessor +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/OptionProcessor.h" +#include "Poco/Util/OptionSet.h" +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionException.h" + + +namespace Poco { +namespace Util { + + +OptionProcessor::OptionProcessor(const OptionSet& options): + _options(options), + _unixStyle(true), + _ignore(false) +{ +} + + +OptionProcessor::~OptionProcessor() +{ +} + + +void OptionProcessor::setUnixStyle(bool flag) +{ + _unixStyle = flag; +} + + +bool OptionProcessor::process(const std::string& argument, std::string& optionName, std::string& optionArg) +{ + optionName.clear(); + optionArg.clear(); + if (!_ignore) + { + if (!_deferredOption.empty()) + return processCommon(argument, false, optionName, optionArg); + else if (_unixStyle) + return processUnix(argument, optionName, optionArg); + else + return processDefault(argument, optionName, optionArg); + } + return false; +} + + +void OptionProcessor::checkRequired() const +{ + for (OptionSet::Iterator it = _options.begin(); it != _options.end(); ++it) + { + if (it->required() && _specifiedOptions.find(it->fullName()) == _specifiedOptions.end()) + throw MissingOptionException(it->fullName()); + } + if (!_deferredOption.empty()) + { + std::string optionArg; + const Option& option = _options.getOption(_deferredOption, false); + option.process(_deferredOption, optionArg); // will throw MissingArgumentException + } +} + + +bool OptionProcessor::processUnix(const std::string& argument, std::string& optionName, std::string& optionArg) +{ + std::string::const_iterator it = argument.begin(); + std::string::const_iterator end = argument.end(); + if (it != end) + { + if (*it == '-') + { + ++it; + if (it != end) + { + if (*it == '-') + { + ++it; + if (it == end) + { + _ignore = true; + return true; + } + else return processCommon(std::string(it, end), false, optionName, optionArg); + } + else return processCommon(std::string(it, end), true, optionName, optionArg); + } + } + } + return false; +} + + +bool OptionProcessor::processDefault(const std::string& argument, std::string& optionName, std::string& optionArg) +{ + std::string::const_iterator it = argument.begin(); + std::string::const_iterator end = argument.end(); + if (it != end) + { + if (*it == '/') + { + ++it; + return processCommon(std::string(it, end), false, optionName, optionArg); + } + } + return false; +} + + +bool OptionProcessor::processCommon(const std::string& optionStr, bool isShort, std::string& optionName, std::string& optionArg) +{ + if (!_deferredOption.empty()) + { + const Option& option = _options.getOption(_deferredOption, false); + std::string optionWithArg(_deferredOption); + _deferredOption.clear(); + optionWithArg += '='; + optionWithArg += optionStr; + option.process(optionWithArg, optionArg); + optionName = option.fullName(); + return true; + } + if (optionStr.empty()) throw EmptyOptionException(); + const Option& option = _options.getOption(optionStr, isShort); + const std::string& group = option.group(); + if (!group.empty()) + { + if (_groups.find(group) != _groups.end()) + throw IncompatibleOptionsException(option.fullName()); + else + _groups.insert(group); + } + if (_specifiedOptions.find(option.fullName()) != _specifiedOptions.end() && !option.repeatable()) + throw DuplicateOptionException(option.fullName()); + _specifiedOptions.insert(option.fullName()); + if (option.argumentRequired() && ((!isShort && optionStr.find_first_of(":=") == std::string::npos) || (isShort && optionStr.length() == option.shortName().length()))) + { + _deferredOption = option.fullName(); + return true; + } + option.process(optionStr, optionArg); + optionName = option.fullName(); + return true; +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/OptionSet.cpp b/contrib/libs/poco/Util/src/OptionSet.cpp new file mode 100644 index 0000000000..bfda7b7691 --- /dev/null +++ b/contrib/libs/poco/Util/src/OptionSet.cpp @@ -0,0 +1,122 @@ +// +// OptionSet.cpp +// +// Library: Util +// Package: Options +// Module: OptionSet +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/OptionSet.h" +#include "Poco/Util/OptionException.h" +#include "Poco/Exception.h" + + +namespace Poco { +namespace Util { + + +OptionSet::OptionSet() +{ +} + + +OptionSet::OptionSet(const OptionSet& options): + _options(options._options) +{ +} + + +OptionSet::~OptionSet() +{ +} + + +OptionSet& OptionSet::operator = (const OptionSet& options) +{ + if (&options != this) + _options = options._options; + return *this; +} + + +void OptionSet::addOption(const Option& option) +{ + poco_assert (!option.fullName().empty()); + OptionVec::const_iterator it = _options.begin(); + OptionVec::const_iterator itEnd = _options.end(); + for (; it != itEnd; ++it) + { + if (it->fullName() == option.fullName()) + { + throw DuplicateOptionException(it->fullName()); + } + } + + _options.push_back(option); +} + + +bool OptionSet::hasOption(const std::string& name, bool matchShort) const +{ + bool found = false; + for (Iterator it = _options.begin(); it != _options.end(); ++it) + { + if ((matchShort && it->matchesShort(name)) || (!matchShort && it->matchesFull(name))) + { + if (!found) + found = true; + else + return false; + } + } + return found; +} + + +const Option& OptionSet::getOption(const std::string& name, bool matchShort) const +{ + const Option* pOption = 0; + for (Iterator it = _options.begin(); it != _options.end(); ++it) + { + if ((matchShort && it->matchesShort(name)) || (!matchShort && it->matchesPartial(name))) + { + if (!pOption) + { + pOption = &*it; + if (!matchShort && it->matchesFull(name)) + break; + } + else if (!matchShort && it->matchesFull(name)) + { + pOption = &*it; + break; + } + else throw AmbiguousOptionException(name); + } + } + if (pOption) + return *pOption; + else + throw UnknownOptionException(name); +} + + +OptionSet::Iterator OptionSet::begin() const +{ + return _options.begin(); +} + + +OptionSet::Iterator OptionSet::end() const +{ + return _options.end(); +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/PropertyFileConfiguration.cpp b/contrib/libs/poco/Util/src/PropertyFileConfiguration.cpp new file mode 100644 index 0000000000..dbdc811403 --- /dev/null +++ b/contrib/libs/poco/Util/src/PropertyFileConfiguration.cpp @@ -0,0 +1,190 @@ +// +// PropertyFileConfiguration.cpp +// +// Library: Util +// Package: Configuration +// Module: PropertyFileConfiguration +// +// Copyright (c) 2004-2009, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/PropertyFileConfiguration.h" +#include "Poco/Exception.h" +#include "Poco/String.h" +#include "Poco/Path.h" +#include "Poco/FileStream.h" +#include "Poco/LineEndingConverter.h" +#include "Poco/Ascii.h" + + +using Poco::trim; +using Poco::Path; + + +namespace Poco { +namespace Util { + + +PropertyFileConfiguration::PropertyFileConfiguration() +{ +} + + +PropertyFileConfiguration::PropertyFileConfiguration(std::istream& istr) +{ + load(istr); +} + + +PropertyFileConfiguration::PropertyFileConfiguration(const std::string& path) +{ + load(path); +} + + +PropertyFileConfiguration::~PropertyFileConfiguration() +{ +} + + +void PropertyFileConfiguration::load(std::istream& istr) +{ + clear(); + while (!istr.eof()) + { + parseLine(istr); + } +} + + +void PropertyFileConfiguration::load(const std::string& path) +{ + Poco::FileInputStream istr(path); + if (istr.good()) + load(istr); + else + throw Poco::OpenFileException(path); +} + + +void PropertyFileConfiguration::save(std::ostream& ostr) const +{ + MapConfiguration::iterator it = begin(); + MapConfiguration::iterator ed = end(); + while (it != ed) + { + ostr << it->first << ": "; + for (std::string::const_iterator its = it->second.begin(); its != it->second.end(); ++its) + { + switch (*its) + { + case '\t': + ostr << "\\t"; + break; + case '\r': + ostr << "\\r"; + break; + case '\n': + ostr << "\\n"; + break; + case '\f': + ostr << "\\f"; + break; + case '\\': + ostr << "\\\\"; + break; + default: + ostr << *its; + break; + } + } + ostr << "\n"; + ++it; + } +} + + +void PropertyFileConfiguration::save(const std::string& path) const +{ + Poco::FileOutputStream ostr(path); + if (ostr.good()) + { + Poco::OutputLineEndingConverter lec(ostr); + save(lec); + lec.flush(); + ostr.flush(); + if (!ostr.good()) throw Poco::WriteFileException(path); + } + else throw Poco::CreateFileException(path); +} + + +void PropertyFileConfiguration::parseLine(std::istream& istr) +{ + static const int eof = std::char_traits<char>::eof(); + + int c = istr.get(); + while (c != eof && Poco::Ascii::isSpace(c)) c = istr.get(); + if (c != eof) + { + if (c == '#' || c == '!') + { + while (c != eof && c != '\n' && c != '\r') c = istr.get(); + } + else + { + std::string key; + while (c != eof && c != '=' && c != ':' && c != '\r' && c != '\n') { key += (char) c; c = istr.get(); } + std::string value; + if (c == '=' || c == ':') + { + c = readChar(istr); + while (c != eof && c) { value += (char) c; c = readChar(istr); } + } + setRaw(trim(key), trim(value)); + } + } +} + + +int PropertyFileConfiguration::readChar(std::istream& istr) +{ + for (;;) + { + int c = istr.get(); + if (c == '\\') + { + c = istr.get(); + switch (c) + { + case 't': + return '\t'; + case 'r': + return '\r'; + case 'n': + return '\n'; + case 'f': + return '\f'; + case '\r': + if (istr.peek() == '\n') + istr.get(); + continue; + case '\n': + continue; + default: + return c; + } + } + else if (c == '\n' || c == '\r') + return 0; + else + return c; + } +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/RegExpValidator.cpp b/contrib/libs/poco/Util/src/RegExpValidator.cpp new file mode 100644 index 0000000000..1553340650 --- /dev/null +++ b/contrib/libs/poco/Util/src/RegExpValidator.cpp @@ -0,0 +1,47 @@ +// +// RegExpValidator.cpp +// +// Library: Util +// Package: Options +// Module: RegExpValidator +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/RegExpValidator.h" +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionException.h" +#include "Poco/RegularExpression.h" +#include "Poco/Format.h" + + +using Poco::format; + + +namespace Poco { +namespace Util { + + +RegExpValidator::RegExpValidator(const std::string& regexp): + _regexp(regexp) +{ +} + + +RegExpValidator::~RegExpValidator() +{ +} + + +void RegExpValidator::validate(const Option& option, const std::string& value) +{ + if (!RegularExpression::match(value, _regexp, RegularExpression::RE_ANCHORED | RegularExpression::RE_UTF8)) + throw InvalidArgumentException(format("argument for %s does not match regular expression %s", option.fullName(), _regexp)); +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/ServerApplication.cpp b/contrib/libs/poco/Util/src/ServerApplication.cpp new file mode 100644 index 0000000000..e427c0906c --- /dev/null +++ b/contrib/libs/poco/Util/src/ServerApplication.cpp @@ -0,0 +1,749 @@ +// +// ServerApplication.cpp +// +// Library: Util +// Package: Application +// Module: ServerApplication +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/ServerApplication.h" +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionSet.h" +#include "Poco/Util/OptionException.h" +#include "Poco/FileStream.h" +#include "Poco/Exception.h" +#if !defined(POCO_VXWORKS) +#include "Poco/Process.h" +#include "Poco/NamedEvent.h" +#endif +#include "Poco/NumberFormatter.h" +#include "Poco/Logger.h" +#include "Poco/String.h" +#if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS) +#include "Poco/TemporaryFile.h" +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <signal.h> +#include <sys/stat.h> +#include <fstream> +#elif defined(POCO_OS_FAMILY_WINDOWS) +#if !defined(_WIN32_WCE) +#include "Poco/Util/WinService.h" +#include "Poco/Util/WinRegistryKey.h" +#endif +#include "Poco/UnWindows.h" +#include <cstring> +#endif +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) +#include "Poco/UnicodeConverter.h" +#endif + + +using Poco::NumberFormatter; +using Poco::Exception; +using Poco::SystemException; + + +namespace Poco { +namespace Util { + + +#if defined(POCO_OS_FAMILY_WINDOWS) +Poco::NamedEvent ServerApplication::_terminate(Poco::ProcessImpl::terminationEventName(Poco::Process::id())); +#if !defined(_WIN32_WCE) +Poco::Event ServerApplication::_terminated; +SERVICE_STATUS ServerApplication::_serviceStatus; +SERVICE_STATUS_HANDLE ServerApplication::_serviceStatusHandle = 0; +#endif +#endif +#if defined(POCO_VXWORKS) || POCO_OS == POCO_OS_ANDROID +Poco::Event ServerApplication::_terminate; +#endif + + +ServerApplication::ServerApplication() +{ +#if defined(POCO_OS_FAMILY_WINDOWS) +#if !defined(_WIN32_WCE) + _action = SRV_RUN; + std::memset(&_serviceStatus, 0, sizeof(_serviceStatus)); +#endif +#endif +} + + +ServerApplication::~ServerApplication() +{ +} + + +bool ServerApplication::isInteractive() const +{ + bool runsInBackground = config().getBool("application.runAsDaemon", false) || config().getBool("application.runAsService", false); + return !runsInBackground; +} + + +int ServerApplication::run() +{ + return Application::run(); +} + + +void ServerApplication::terminate() +{ +#if defined(POCO_OS_FAMILY_WINDOWS) + _terminate.set(); +#elif defined(POCO_VXWORKS) || POCO_OS == POCO_OS_ANDROID + _terminate.set(); +#else + Poco::Process::requestTermination(Process::id()); +#endif +} + + +#if defined(POCO_OS_FAMILY_WINDOWS) +#if !defined(_WIN32_WCE) + + +// +// Windows specific code +// +BOOL ServerApplication::ConsoleCtrlHandler(DWORD ctrlType) +{ + switch (ctrlType) + { + case CTRL_C_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_BREAK_EVENT: + terminate(); + return _terminated.tryWait(10000) ? TRUE : FALSE; + default: + return FALSE; + } +} + + +void ServerApplication::ServiceControlHandler(DWORD control) +{ + switch (control) + { + case SERVICE_CONTROL_STOP: + case SERVICE_CONTROL_SHUTDOWN: + terminate(); + _serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; + break; + case SERVICE_CONTROL_INTERROGATE: + break; + } + SetServiceStatus(_serviceStatusHandle, &_serviceStatus); +} + + +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) +void ServerApplication::ServiceMain(DWORD argc, LPWSTR* argv) +#else +void ServerApplication::ServiceMain(DWORD argc, LPTSTR* argv) +#endif +{ + ServerApplication& app = static_cast<ServerApplication&>(Application::instance()); + + app.config().setBool("application.runAsService", true); + +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) + _serviceStatusHandle = RegisterServiceCtrlHandlerW(L"", ServiceControlHandler); +#else + _serviceStatusHandle = RegisterServiceCtrlHandlerA("", ServiceControlHandler); +#endif + if (!_serviceStatusHandle) + throw SystemException("cannot register service control handler"); + + _serviceStatus.dwServiceType = SERVICE_WIN32; + _serviceStatus.dwCurrentState = SERVICE_START_PENDING; + _serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; + _serviceStatus.dwWin32ExitCode = 0; + _serviceStatus.dwServiceSpecificExitCode = 0; + _serviceStatus.dwCheckPoint = 0; + _serviceStatus.dwWaitHint = 0; + SetServiceStatus(_serviceStatusHandle, &_serviceStatus); + + try + { +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) + std::vector<std::string> args; + for (DWORD i = 0; i < argc; ++i) + { + std::string arg; + Poco::UnicodeConverter::toUTF8(argv[i], arg); + args.push_back(arg); + } + app.init(args); +#else + app.init(argc, argv); +#endif + _serviceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus(_serviceStatusHandle, &_serviceStatus); + int rc = app.run(); + _serviceStatus.dwWin32ExitCode = rc ? ERROR_SERVICE_SPECIFIC_ERROR : 0; + _serviceStatus.dwServiceSpecificExitCode = rc; + } + catch (Exception& exc) + { + app.logger().log(exc); + _serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; + _serviceStatus.dwServiceSpecificExitCode = EXIT_CONFIG; + } + catch (...) + { + app.logger().error("fatal error - aborting"); + _serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; + _serviceStatus.dwServiceSpecificExitCode = EXIT_SOFTWARE; + } + _serviceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(_serviceStatusHandle, &_serviceStatus); +} + + +void ServerApplication::waitForTerminationRequest() +{ + SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE); + _terminate.wait(); + _terminated.set(); +} + + +int ServerApplication::run(int argc, char** argv) +{ + if (!hasConsole() && isService()) + { + return 0; + } + else + { + int rc = EXIT_OK; + try + { + init(argc, argv); + switch (_action) + { + case SRV_REGISTER: + registerService(); + rc = EXIT_OK; + break; + case SRV_UNREGISTER: + unregisterService(); + rc = EXIT_OK; + break; + default: + rc = run(); + } + } + catch (Exception& exc) + { + logger().log(exc); + rc = EXIT_SOFTWARE; + } + return rc; + } +} + + +int ServerApplication::run(const std::vector<std::string>& args) +{ + if (!hasConsole() && isService()) + { + return 0; + } + else + { + int rc = EXIT_OK; + try + { + init(args); + switch (_action) + { + case SRV_REGISTER: + registerService(); + rc = EXIT_OK; + break; + case SRV_UNREGISTER: + unregisterService(); + rc = EXIT_OK; + break; + default: + rc = run(); + } + } + catch (Exception& exc) + { + logger().log(exc); + rc = EXIT_SOFTWARE; + } + return rc; + } +} + + +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) +int ServerApplication::run(int argc, wchar_t** argv) +{ + if (!hasConsole() && isService()) + { + return 0; + } + else + { + int rc = EXIT_OK; + try + { + init(argc, argv); + switch (_action) + { + case SRV_REGISTER: + registerService(); + rc = EXIT_OK; + break; + case SRV_UNREGISTER: + unregisterService(); + rc = EXIT_OK; + break; + default: + rc = run(); + } + } + catch (Exception& exc) + { + logger().log(exc); + rc = EXIT_SOFTWARE; + } + return rc; + } +} +#endif + + +bool ServerApplication::isService() +{ +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) + SERVICE_TABLE_ENTRYW svcDispatchTable[2]; + svcDispatchTable[0].lpServiceName = L""; + svcDispatchTable[0].lpServiceProc = ServiceMain; + svcDispatchTable[1].lpServiceName = NULL; + svcDispatchTable[1].lpServiceProc = NULL; + return StartServiceCtrlDispatcherW(svcDispatchTable) != 0; +#else + SERVICE_TABLE_ENTRY svcDispatchTable[2]; + svcDispatchTable[0].lpServiceName = ""; + svcDispatchTable[0].lpServiceProc = ServiceMain; + svcDispatchTable[1].lpServiceName = NULL; + svcDispatchTable[1].lpServiceProc = NULL; + return StartServiceCtrlDispatcherA(svcDispatchTable) != 0; +#endif +} + + +bool ServerApplication::hasConsole() +{ + HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + return hStdOut != INVALID_HANDLE_VALUE && hStdOut != NULL; +} + + +void ServerApplication::registerService() +{ + std::string name = config().getString("application.baseName"); + std::string path = config().getString("application.path"); + + WinService service(name); + if (_displayName.empty()) + service.registerService(path); + else + service.registerService(path, _displayName); + if (_startup == "auto") + service.setStartup(WinService::SVC_AUTO_START); + else if (_startup == "manual") + service.setStartup(WinService::SVC_MANUAL_START); + if (!_description.empty()) + service.setDescription(_description); + logger().information("The application has been successfully registered as a service."); +} + + +void ServerApplication::unregisterService() +{ + std::string name = config().getString("application.baseName"); + + WinService service(name); + service.unregisterService(); + logger().information("The service has been successfully unregistered."); +} + + +void ServerApplication::defineOptions(OptionSet& options) +{ + Application::defineOptions(options); + + options.addOption( + Option("registerService", "", "Register the application as a service.") + .required(false) + .repeatable(false) + .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleRegisterService))); + + options.addOption( + Option("unregisterService", "", "Unregister the application as a service.") + .required(false) + .repeatable(false) + .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleUnregisterService))); + + options.addOption( + Option("displayName", "", "Specify a display name for the service (only with /registerService).") + .required(false) + .repeatable(false) + .argument("name") + .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDisplayName))); + + options.addOption( + Option("description", "", "Specify a description for the service (only with /registerService).") + .required(false) + .repeatable(false) + .argument("text") + .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDescription))); + + options.addOption( + Option("startup", "", "Specify the startup mode for the service (only with /registerService).") + .required(false) + .repeatable(false) + .argument("automatic|manual") + .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleStartup))); +} + + +void ServerApplication::handleRegisterService(const std::string& /*name*/, const std::string& /*value*/) +{ + _action = SRV_REGISTER; +} + + +void ServerApplication::handleUnregisterService(const std::string& /*name*/, const std::string& /*value*/) +{ + _action = SRV_UNREGISTER; +} + + +void ServerApplication::handleDisplayName(const std::string& /*name*/, const std::string& value) +{ + _displayName = value; +} + + +void ServerApplication::handleDescription(const std::string& /*name*/, const std::string& value) +{ + _description = value; +} + + +void ServerApplication::handleStartup(const std::string& /*name*/, const std::string& value) +{ + if (Poco::icompare(value, 4, std::string("auto")) == 0) + _startup = "auto"; + else if (Poco::icompare(value, std::string("manual")) == 0) + _startup = "manual"; + else + throw InvalidArgumentException("argument to startup option must be 'auto[matic]' or 'manual'"); +} + + +#else // _WIN32_WCE +void ServerApplication::waitForTerminationRequest() +{ + _terminate.wait(); +} + + +int ServerApplication::run(int argc, char** argv) +{ + try + { + init(argc, argv); + } + catch (Exception& exc) + { + logger().log(exc); + return EXIT_CONFIG; + } + return run(); +} + + +int ServerApplication::run(const std::vector<std::string>& args) +{ + try + { + init(args); + } + catch (Exception& exc) + { + logger().log(exc); + return EXIT_CONFIG; + } + return run(); +} + + +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) +int ServerApplication::run(int argc, wchar_t** argv) +{ + try + { + init(argc, argv); + } + catch (Exception& exc) + { + logger().log(exc); + return EXIT_CONFIG; + } + return run(); +} +#endif + + +#endif // _WIN32_WCE +#elif defined(POCO_VXWORKS) +// +// VxWorks specific code +// +void ServerApplication::waitForTerminationRequest() +{ + _terminate.wait(); +} + + +int ServerApplication::run(int argc, char** argv) +{ + try + { + init(argc, argv); + } + catch (Exception& exc) + { + logger().log(exc); + return EXIT_CONFIG; + } + return run(); +} + + +int ServerApplication::run(const std::vector<std::string>& args) +{ + try + { + init(args); + } + catch (Exception& exc) + { + logger().log(exc); + return EXIT_CONFIG; + } + return run(); +} + + +void ServerApplication::defineOptions(OptionSet& options) +{ + Application::defineOptions(options); +} + + +#elif defined(POCO_OS_FAMILY_UNIX) + + +// +// Unix specific code +// +void ServerApplication::waitForTerminationRequest() +{ +#if POCO_OS != POCO_OS_ANDROID + sigset_t sset; + sigemptyset(&sset); + if (!std::getenv("POCO_ENABLE_DEBUGGER")) + { + sigaddset(&sset, SIGINT); + } + sigaddset(&sset, SIGQUIT); + sigaddset(&sset, SIGTERM); + sigprocmask(SIG_BLOCK, &sset, NULL); + int sig; + sigwait(&sset, &sig); +#else // POCO_OS != POCO_OS_ANDROID + _terminate.wait(); +#endif +} + + +int ServerApplication::run(int argc, char** argv) +{ + bool runAsDaemon = isDaemon(argc, argv); + if (runAsDaemon) + { + beDaemon(); + } + try + { + init(argc, argv); + if (runAsDaemon) + { + int rc = chdir("/"); + if (rc != 0) return EXIT_OSERR; + } + } + catch (Exception& exc) + { + logger().log(exc); + return EXIT_CONFIG; + } + return run(); +} + + +int ServerApplication::run(const std::vector<std::string>& args) +{ + bool runAsDaemon = false; + for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) + { + if (*it == "--daemon") + { + runAsDaemon = true; + break; + } + } + if (runAsDaemon) + { + beDaemon(); + } + try + { + init(args); + if (runAsDaemon) + { + int rc = chdir("/"); + if (rc != 0) return EXIT_OSERR; + } + } + catch (Exception& exc) + { + logger().log(exc); + return EXIT_CONFIG; + } + return run(); +} + + +bool ServerApplication::isDaemon(int argc, char** argv) +{ + std::string option("--daemon"); + for (int i = 1; i < argc; ++i) + { + if (option == argv[i]) + return true; + } + return false; +} + + +void ServerApplication::beDaemon() +{ +#if !defined(POCO_NO_FORK_EXEC) + pid_t pid; + if ((pid = fork()) < 0) + throw SystemException("cannot fork daemon process"); + else if (pid != 0) + exit(0); + + setsid(); + umask(027); + + // attach stdin, stdout, stderr to /dev/null + // instead of just closing them. This avoids + // issues with third party/legacy code writing + // stuff to stdout/stderr. + FILE* fin = freopen("/dev/null", "r+", stdin); + if (!fin) throw Poco::OpenFileException("Cannot attach stdin to /dev/null"); + FILE* fout = freopen("/dev/null", "r+", stdout); + if (!fout) throw Poco::OpenFileException("Cannot attach stdout to /dev/null"); + FILE* ferr = freopen("/dev/null", "r+", stderr); + if (!ferr) throw Poco::OpenFileException("Cannot attach stderr to /dev/null"); +#else + throw Poco::NotImplementedException("platform does not allow fork/exec"); +#endif +} + + +void ServerApplication::defineOptions(OptionSet& options) +{ + Application::defineOptions(options); + + options.addOption( + Option("daemon", "", "Run application as a daemon.") + .required(false) + .repeatable(false) + .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDaemon))); + + options.addOption( + Option("umask", "", "Set the daemon's umask (octal, e.g. 027).") + .required(false) + .repeatable(false) + .argument("mask") + .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleUMask))); + + options.addOption( + Option("pidfile", "", "Write the process ID of the application to given file.") + .required(false) + .repeatable(false) + .argument("path") + .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handlePidFile))); +} + + +void ServerApplication::handleDaemon(const std::string& name, const std::string& value) +{ + config().setBool("application.runAsDaemon", true); +} + + +void ServerApplication::handleUMask(const std::string& name, const std::string& value) +{ + int mask = 0; + for (std::string::const_iterator it = value.begin(); it != value.end(); ++it) + { + mask *= 8; + if (*it >= '0' && *it <= '7') + mask += *it - '0'; + else + throw Poco::InvalidArgumentException("umask contains non-octal characters", value); + } + umask(mask); +} + + +void ServerApplication::handlePidFile(const std::string& name, const std::string& value) +{ + Poco::FileOutputStream ostr(value); + if (ostr.good()) + ostr << Poco::Process::id() << std::endl; + else + throw Poco::CreateFileException("Cannot write PID to file", value); + Poco::TemporaryFile::registerForDeletion(value); +} + + +#endif + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/Subsystem.cpp b/contrib/libs/poco/Util/src/Subsystem.cpp new file mode 100644 index 0000000000..5e6ed6c732 --- /dev/null +++ b/contrib/libs/poco/Util/src/Subsystem.cpp @@ -0,0 +1,44 @@ +// +// Subsystem.cpp +// +// Library: Util +// Package: Application +// Module: Subsystem +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/Subsystem.h" + + +namespace Poco { +namespace Util { + + +Subsystem::Subsystem() +{ +} + + +Subsystem::~Subsystem() +{ +} + + +void Subsystem::reinitialize(Application& app) +{ + uninitialize(); + initialize(app); +} + + +void Subsystem::defineOptions(OptionSet& /*options*/) +{ +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/SystemConfiguration.cpp b/contrib/libs/poco/Util/src/SystemConfiguration.cpp new file mode 100644 index 0000000000..f0a4156472 --- /dev/null +++ b/contrib/libs/poco/Util/src/SystemConfiguration.cpp @@ -0,0 +1,212 @@ +// +// SystemConfiguration.cpp +// +// Library: Util +// Package: Configuration +// Module: SystemConfiguration +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/SystemConfiguration.h" +#include "Poco/Environment.h" +#include "Poco/Path.h" +#include "Poco/DateTime.h" +#include "Poco/DateTimeFormatter.h" +#include "Poco/DateTimeFormat.h" +#include "Poco/NumberFormatter.h" +#if !defined(POCO_VXWORKS) +#include "Poco/Process.h" +#endif +#include "Poco/Exception.h" +#include <cstdio> + + +using Poco::Environment; +using Poco::Path; + + +namespace Poco { +namespace Util { + + +const std::string SystemConfiguration::OSNAME = "system.osName"; +const std::string SystemConfiguration::OSVERSION = "system.osVersion"; +const std::string SystemConfiguration::OSARCHITECTURE = "system.osArchitecture"; +const std::string SystemConfiguration::NODENAME = "system.nodeName"; +const std::string SystemConfiguration::NODEID = "system.nodeId"; +const std::string SystemConfiguration::CURRENTDIR = "system.currentDir"; +const std::string SystemConfiguration::HOMEDIR = "system.homeDir"; +const std::string SystemConfiguration::CONFIGHOMEDIR = "system.configHomeDir"; +const std::string SystemConfiguration::CACHEHOMEDIR = "system.cacheHomeDir"; +const std::string SystemConfiguration::DATAHOMEDIR = "system.dataHomeDir"; +const std::string SystemConfiguration::TEMPHOMEDIR = "system.tempHomeDir"; +const std::string SystemConfiguration::TEMPDIR = "system.tempDir"; +const std::string SystemConfiguration::CONFIGDIR = "system.configDir"; +const std::string SystemConfiguration::DATETIME = "system.dateTime"; +#if !defined(POCO_VXWORKS) +const std::string SystemConfiguration::PID = "system.pid"; +#endif +const std::string SystemConfiguration::ENV = "system.env."; + + +SystemConfiguration::SystemConfiguration() +{ +} + + +SystemConfiguration::~SystemConfiguration() +{ +} + + +bool SystemConfiguration::getRaw(const std::string& key, std::string& value) const +{ + if (key == OSNAME) + { + value = Environment::osName(); + } + else if (key == OSVERSION) + { + value = Environment::osVersion(); + } + else if (key == OSARCHITECTURE) + { + value = Environment::osArchitecture(); + } + else if (key == NODENAME) + { + value = Environment::nodeName(); + } + else if (key == NODEID) + { + try + { + Poco::Environment::NodeId id; + Poco::Environment::nodeId(id); + char result[13]; + std::sprintf(result, "%02x%02x%02x%02x%02x%02x", + id[0], + id[1], + id[2], + id[3], + id[4], + id[5]); + value = result; + } + catch (...) + { + value = "000000000000"; + } + } + else if (key == CURRENTDIR) + { + value = Path::current(); + } + else if (key == HOMEDIR) + { + value = Path::home(); + } + else if (key == CONFIGHOMEDIR) + { + value = Path::configHome(); + } + else if (key == CACHEHOMEDIR) + { + value = Path::cacheHome(); + } + else if (key == DATAHOMEDIR) + { + value = Path::dataHome(); + } + + else if (key == TEMPHOMEDIR) + { + value = Path::tempHome(); + } + else if (key == TEMPDIR) + { + value = Path::temp(); + } + else if (key == CONFIGDIR) + { + value = Path::config(); + } + else if (key == DATETIME) + { + value = Poco::DateTimeFormatter::format(Poco::DateTime(), Poco::DateTimeFormat::ISO8601_FORMAT); + } +#if !defined(POCO_VXWORKS) + else if (key == PID) + { + value = "0"; + value = Poco::NumberFormatter::format(Poco::Process::id()); + } +#endif + else if (key.compare(0, ENV.size(), ENV) == 0) + { + return getEnv(key.substr(ENV.size()), value); + } + else return false; + return true; +} + + +void SystemConfiguration::setRaw(const std::string& key, const std::string& /*value*/) +{ + throw Poco::InvalidAccessException("Attempt to modify a system property", key); +} + + +void SystemConfiguration::enumerate(const std::string& key, Keys& range) const +{ + if (key.empty()) + { + range.push_back("system"); + } + else if (key == "system") + { + range.push_back("osName"); + range.push_back("osVersion"); + range.push_back("osArchitecture"); + range.push_back("nodeName"); + range.push_back("nodeId"); + range.push_back("currentDir"); + range.push_back("homeDir"); + range.push_back("configHomeDir"); + range.push_back("cacheHomeDir"); + range.push_back("dataHomeDir"); + range.push_back("tempHomeDir"); + range.push_back("tempDir"); + range.push_back("configDir"); + range.push_back("dateTime"); +#if !defined(POCO_VXWORKS) + range.push_back("pid"); +#endif + range.push_back("env"); + } +} + + +void SystemConfiguration::removeRaw(const std::string& /*key*/) +{ + throw Poco::NotImplementedException("Removing a key in a SystemConfiguration"); +} + + +bool SystemConfiguration::getEnv(const std::string& name, std::string& value) +{ + if (Environment::has(name)) + { + value = Environment::get(name); + return true; + } + return false; +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/Timer.cpp b/contrib/libs/poco/Util/src/Timer.cpp new file mode 100644 index 0000000000..3de4821c16 --- /dev/null +++ b/contrib/libs/poco/Util/src/Timer.cpp @@ -0,0 +1,351 @@ +// +// Timer.cpp +// +// Library: Util +// Package: Timer +// Module: Timer +// +// Copyright (c) 2009, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/Timer.h" +#include "Poco/Notification.h" +#include "Poco/ErrorHandler.h" +#include "Poco/Event.h" + + +using Poco::ErrorHandler; + + +namespace Poco { +namespace Util { + + +class TimerNotification: public Poco::Notification +{ +public: + TimerNotification(Poco::TimedNotificationQueue& queue): + _queue(queue) + { + } + + ~TimerNotification() + { + } + + virtual bool execute() = 0; + + Poco::TimedNotificationQueue& queue() + { + return _queue; + } + +private: + Poco::TimedNotificationQueue& _queue; +}; + + +class StopNotification: public TimerNotification +{ +public: + StopNotification(Poco::TimedNotificationQueue& queue): + TimerNotification(queue) + { + } + + ~StopNotification() + { + } + + bool execute() + { + queue().clear(); + return false; + } +}; + + +class CancelNotification: public TimerNotification +{ +public: + CancelNotification(Poco::TimedNotificationQueue& queue): + TimerNotification(queue) + { + } + + ~CancelNotification() + { + } + + bool execute() + { + // Check if there's a StopNotification pending. + Poco::AutoPtr<TimerNotification> pNf = static_cast<TimerNotification*>(queue().dequeueNotification()); + while (pNf) + { + if (pNf.cast<StopNotification>()) + { + queue().clear(); + _finished.set(); + return false; + } + pNf = static_cast<TimerNotification*>(queue().dequeueNotification()); + } + + queue().clear(); + _finished.set(); + return true; + } + + void wait() + { + _finished.wait(); + } + +private: + Poco::Event _finished; +}; + + +class TaskNotification: public TimerNotification +{ +public: + TaskNotification(Poco::TimedNotificationQueue& queue, TimerTask::Ptr pTask): + TimerNotification(queue), + _pTask(pTask) + { + } + + ~TaskNotification() + { + } + + TimerTask::Ptr task() + { + return _pTask; + } + + bool execute() + { + if (!_pTask->isCancelled()) + { + try + { + _pTask->_lastExecution.update(); + _pTask->run(); + } + catch (Exception& exc) + { + ErrorHandler::handle(exc); + } + catch (std::exception& exc) + { + ErrorHandler::handle(exc); + } + catch (...) + { + ErrorHandler::handle(); + } + } + return true; + } + +private: + TimerTask::Ptr _pTask; +}; + + +class PeriodicTaskNotification: public TaskNotification +{ +public: + PeriodicTaskNotification(Poco::TimedNotificationQueue& queue, TimerTask::Ptr pTask, long interval): + TaskNotification(queue, pTask), + _interval(interval) + { + } + + ~PeriodicTaskNotification() + { + } + + bool execute() + { + TaskNotification::execute(); + + if (!task()->isCancelled()) + { + Poco::Clock now; + Poco::Clock nextExecution; + nextExecution += static_cast<Poco::Clock::ClockDiff>(_interval)*1000; + if (nextExecution < now) nextExecution = now; + queue().enqueueNotification(this, nextExecution); + duplicate(); + } + return true; + } + +private: + long _interval; +}; + + +class FixedRateTaskNotification: public TaskNotification +{ +public: + FixedRateTaskNotification(Poco::TimedNotificationQueue& queue, TimerTask::Ptr pTask, long interval, Poco::Clock clock): + TaskNotification(queue, pTask), + _interval(interval), + _nextExecution(clock) + { + } + + ~FixedRateTaskNotification() + { + } + + bool execute() + { + TaskNotification::execute(); + + if (!task()->isCancelled()) + { + Poco::Clock now; + _nextExecution += static_cast<Poco::Clock::ClockDiff>(_interval)*1000; + if (_nextExecution < now) _nextExecution = now; + queue().enqueueNotification(this, _nextExecution); + duplicate(); + } + return true; + } + +private: + long _interval; + Poco::Clock _nextExecution; +}; + + +Timer::Timer() +{ + _thread.start(*this); +} + + +Timer::Timer(Poco::Thread::Priority priority) +{ + _thread.setPriority(priority); + _thread.start(*this); +} + + +Timer::~Timer() +{ + try + { + _queue.enqueueNotification(new StopNotification(_queue), Poco::Clock(0)); + _thread.join(); + } + catch (...) + { + poco_unexpected(); + } +} + + +void Timer::cancel(bool wait) +{ + Poco::AutoPtr<CancelNotification> pNf = new CancelNotification(_queue); + _queue.enqueueNotification(pNf, Poco::Clock(0)); + if (wait) + { + pNf->wait(); + } +} + + +void Timer::schedule(TimerTask::Ptr pTask, Poco::Timestamp time) +{ + validateTask(pTask); + _queue.enqueueNotification(new TaskNotification(_queue, pTask), time); +} + + +void Timer::schedule(TimerTask::Ptr pTask, Poco::Clock clock) +{ + validateTask(pTask); + _queue.enqueueNotification(new TaskNotification(_queue, pTask), clock); +} + + +void Timer::schedule(TimerTask::Ptr pTask, long delay, long interval) +{ + Poco::Clock clock; + clock += static_cast<Poco::Clock::ClockDiff>(delay)*1000; + schedule(pTask, clock, interval); +} + + +void Timer::schedule(TimerTask::Ptr pTask, Poco::Timestamp time, long interval) +{ + validateTask(pTask); + _queue.enqueueNotification(new PeriodicTaskNotification(_queue, pTask, interval), time); +} + + +void Timer::schedule(TimerTask::Ptr pTask, Poco::Clock clock, long interval) +{ + validateTask(pTask); + _queue.enqueueNotification(new PeriodicTaskNotification(_queue, pTask, interval), clock); +} + + +void Timer::scheduleAtFixedRate(TimerTask::Ptr pTask, long delay, long interval) +{ + Poco::Clock clock; + clock += static_cast<Poco::Clock::ClockDiff>(delay)*1000; + scheduleAtFixedRate(pTask, clock, interval); +} + + +void Timer::scheduleAtFixedRate(TimerTask::Ptr pTask, Poco::Timestamp time, long interval) +{ + validateTask(pTask); + Poco::Timestamp tsNow; + Poco::Clock clock; + Poco::Timestamp::TimeDiff diff = time - tsNow; + clock += diff; + _queue.enqueueNotification(new FixedRateTaskNotification(_queue, pTask, interval, clock), clock); +} + + +void Timer::scheduleAtFixedRate(TimerTask::Ptr pTask, Poco::Clock clock, long interval) +{ + validateTask(pTask); + _queue.enqueueNotification(new FixedRateTaskNotification(_queue, pTask, interval, clock), clock); +} + + +void Timer::run() +{ + bool cont = true; + while (cont) + { + Poco::AutoPtr<TimerNotification> pNf = static_cast<TimerNotification*>(_queue.waitDequeueNotification()); + cont = pNf->execute(); + } +} + + +void Timer::validateTask(const TimerTask::Ptr& pTask) +{ + if (pTask->isCancelled()) + { + throw Poco::IllegalStateException("A cancelled task must not be rescheduled"); + } +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/TimerTask.cpp b/contrib/libs/poco/Util/src/TimerTask.cpp new file mode 100644 index 0000000000..dac3794d1c --- /dev/null +++ b/contrib/libs/poco/Util/src/TimerTask.cpp @@ -0,0 +1,40 @@ +// +// TimerTask.cpp +// +// Library: Util +// Package: Timer +// Module: TimerTask +// +// Copyright (c) 2009, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/TimerTask.h" + + +namespace Poco { +namespace Util { + + +TimerTask::TimerTask(): + _lastExecution(0), + _isCancelled(false) +{ +} + + +TimerTask::~TimerTask() +{ +} + + +void TimerTask::cancel() +{ + _isCancelled = true; +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/Validator.cpp b/contrib/libs/poco/Util/src/Validator.cpp new file mode 100644 index 0000000000..bc596db289 --- /dev/null +++ b/contrib/libs/poco/Util/src/Validator.cpp @@ -0,0 +1,32 @@ +// +// Validator.cpp +// +// Library: Util +// Package: Options +// Module: Validator +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/Validator.h" + + +namespace Poco { +namespace Util { + + +Validator::Validator() +{ +} + + +Validator::~Validator() +{ +} + + +} } // namespace Poco::Util diff --git a/contrib/libs/poco/Util/src/XMLConfiguration.cpp b/contrib/libs/poco/Util/src/XMLConfiguration.cpp new file mode 100644 index 0000000000..a4b655b9d9 --- /dev/null +++ b/contrib/libs/poco/Util/src/XMLConfiguration.cpp @@ -0,0 +1,479 @@ +// +// XMLConfiguration.cpp +// +// Library: Util +// Package: Configuration +// Module: XMLConfiguration +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Util/XMLConfiguration.h" + + +#ifndef POCO_UTIL_NO_XMLCONFIGURATION + + +#include "Poco/SAX/InputSource.h" +#include "Poco/DOM/DOMParser.h" +#include "Poco/DOM/Element.h" +#include "Poco/DOM/Attr.h" +#include "Poco/DOM/Text.h" +#include "Poco/XML/XMLWriter.h" +#include "Poco/Exception.h" +#include "Poco/NumberParser.h" +#include "Poco/NumberFormatter.h" +#include <set> + + +namespace Poco { +namespace Util { + + +XMLConfiguration::XMLConfiguration(): + _delim('.') +{ + loadEmpty("config"); +} + + +XMLConfiguration::XMLConfiguration(char delim): + _delim(delim) +{ + loadEmpty("config"); +} + + +XMLConfiguration::XMLConfiguration(Poco::XML::InputSource* pInputSource): + _delim('.') +{ + load(pInputSource); +} + + +XMLConfiguration::XMLConfiguration(Poco::XML::InputSource* pInputSource, char delim): + _delim(delim) +{ + load(pInputSource); +} + + +XMLConfiguration::XMLConfiguration(std::istream& istr): + _delim('.') +{ + load(istr); +} + + +XMLConfiguration::XMLConfiguration(std::istream& istr, char delim): + _delim(delim) +{ + load(istr); +} + + +XMLConfiguration::XMLConfiguration(const std::string& path): + _delim('.') +{ + load(path); +} + + +XMLConfiguration::XMLConfiguration(const std::string& path, char delim): + _delim(delim) +{ + load(path); +} + + +XMLConfiguration::XMLConfiguration(const Poco::XML::Document* pDocument): + _delim('.') +{ + load(pDocument); +} + + +XMLConfiguration::XMLConfiguration(const Poco::XML::Document* pDocument, char delim): + _delim(delim) +{ + load(pDocument); +} + + +XMLConfiguration::XMLConfiguration(const Poco::XML::Node* pNode): + _delim('.') +{ + load(pNode); +} + + +XMLConfiguration::XMLConfiguration(const Poco::XML::Node* pNode, char delim): + _delim(delim) +{ + load(pNode); +} + + +XMLConfiguration::~XMLConfiguration() +{ +} + + +void XMLConfiguration::load(Poco::XML::InputSource* pInputSource, unsigned long namePoolSize) +{ + poco_check_ptr (pInputSource); + + Poco::XML::DOMParser parser(namePoolSize); + parser.setFeature(Poco::XML::XMLReader::FEATURE_NAMESPACES, false); + parser.setFeature(Poco::XML::DOMParser::FEATURE_FILTER_WHITESPACE, true); + Poco::XML::AutoPtr<Poco::XML::Document> pDoc = parser.parse(pInputSource); + load(pDoc); +} + + +void XMLConfiguration::load(Poco::XML::InputSource* pInputSource) +{ + load(pInputSource, POCO_XML_NAMEPOOL_DEFAULT_SIZE); +} + + +void XMLConfiguration::load(std::istream& istr) +{ + Poco::XML::InputSource src(istr); + load(&src); +} + + +void XMLConfiguration::load(const std::string& path) +{ + Poco::XML::InputSource src(path); + load(&src); +} + + +void XMLConfiguration::load(const Poco::XML::Document* pDocument) +{ + poco_check_ptr (pDocument); + + _pDocument = Poco::XML::AutoPtr<Poco::XML::Document>(const_cast<Poco::XML::Document*>(pDocument), true); + _pRoot = Poco::XML::AutoPtr<Poco::XML::Node>(pDocument->documentElement(), true); +} + + +void XMLConfiguration::load(const Poco::XML::Node* pNode) +{ + poco_check_ptr (pNode); + + if (pNode->nodeType() == Poco::XML::Node::DOCUMENT_NODE) + { + load(static_cast<const Poco::XML::Document*>(pNode)); + } + else + { + _pDocument = Poco::XML::AutoPtr<Poco::XML::Document>(pNode->ownerDocument(), true); + _pRoot = Poco::XML::AutoPtr<Poco::XML::Node>(const_cast<Poco::XML::Node*>(pNode), true); + } +} + + +void XMLConfiguration::loadEmpty(const std::string& rootElementName) +{ + _pDocument = new Poco::XML::Document; + _pRoot = _pDocument->createElement(rootElementName); + _pDocument->appendChild(_pRoot); +} + + +void XMLConfiguration::save(const std::string& path) const +{ + Poco::XML::DOMWriter writer; + writer.setNewLine("\n"); + writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT); + writer.writeNode(path, _pDocument); +} + + +void XMLConfiguration::save(std::ostream& ostr) const +{ + Poco::XML::DOMWriter writer; + writer.setNewLine("\n"); + writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT); + writer.writeNode(ostr, _pDocument); +} + + +void XMLConfiguration::save(Poco::XML::DOMWriter& writer, const std::string& path) const +{ + writer.writeNode(path, _pDocument); +} + + +void XMLConfiguration::save(Poco::XML::DOMWriter& writer, std::ostream& ostr) const +{ + writer.writeNode(ostr, _pDocument); +} + + +bool XMLConfiguration::getRaw(const std::string& key, std::string& value) const +{ + const Poco::XML::Node* pNode = findNode(key); + if (pNode) + { + value = pNode->innerText(); + return true; + } + else return false; +} + + +void XMLConfiguration::setRaw(const std::string& key, const std::string& value) +{ + std::string::const_iterator it = key.begin(); + Poco::XML::Node* pNode = findNode(it, key.end(), _pRoot, true); + if (pNode) + { + unsigned short nodeType = pNode->nodeType(); + if (Poco::XML::Node::ATTRIBUTE_NODE == nodeType) + { + pNode->setNodeValue(value); + } + else if (Poco::XML::Node::ELEMENT_NODE == nodeType) + { + Poco::XML::Node* pChildNode = pNode->firstChild(); + if (pChildNode) + { + if (Poco::XML::Node::TEXT_NODE == pChildNode->nodeType()) + { + pChildNode->setNodeValue(value); + } + } + else + { + Poco::AutoPtr<Poco::XML::Node> pText = _pDocument->createTextNode(value); + pNode->appendChild(pText); + } + } + } + else throw NotFoundException("Node not found in XMLConfiguration", key); +} + + +void XMLConfiguration::enumerate(const std::string& key, Keys& range) const +{ + using Poco::NumberFormatter; + + std::multiset<std::string> keys; + const Poco::XML::Node* pNode = findNode(key); + if (pNode) + { + const Poco::XML::Node* pChild = pNode->firstChild(); + while (pChild) + { + if (pChild->nodeType() == Poco::XML::Node::ELEMENT_NODE) + { + const std::string& nodeName = pChild->nodeName(); + int n = (int) keys.count(nodeName); + if (n) + range.push_back(nodeName + "[" + NumberFormatter::format(n) + "]"); + else + range.push_back(nodeName); + keys.insert(nodeName); + } + pChild = pChild->nextSibling(); + } + } +} + + +void XMLConfiguration::removeRaw(const std::string& key) +{ + Poco::XML::Node* pNode = findNode(key); + + if (pNode) + { + if (pNode->nodeType() == Poco::XML::Node::ELEMENT_NODE) + { + Poco::XML::Node* pParent = pNode->parentNode(); + if (pParent) + { + pParent->removeChild(pNode); + } + } + else if (pNode->nodeType() == Poco::XML::Node::ATTRIBUTE_NODE) + { + Poco::XML::Attr* pAttr = dynamic_cast<Poco::XML::Attr*>(pNode); + Poco::XML::Element* pOwner = pAttr->ownerElement(); + if (pOwner) + { + pOwner->removeAttributeNode(pAttr); + } + } + } +} + + +const Poco::XML::Node* XMLConfiguration::findNode(const std::string& key) const +{ + std::string::const_iterator it = key.begin(); + Poco::XML::Node* pRoot = const_cast<Poco::XML::Node*>(_pRoot.get()); + return findNode(it, key.end(), pRoot); +} + + +Poco::XML::Node* XMLConfiguration::findNode(const std::string& key) +{ + std::string::const_iterator it = key.begin(); + Poco::XML::Node* pRoot = const_cast<Poco::XML::Node*>(_pRoot.get()); + return findNode(it, key.end(), pRoot); +} + + +Poco::XML::Node* XMLConfiguration::findNode(std::string::const_iterator& it, const std::string::const_iterator& end, Poco::XML::Node* pNode, bool create) const +{ + if (pNode && it != end) + { + if (*it == '[') + { + ++it; + if (it != end && *it == '@') + { + ++it; + std::string attr; + while (it != end && *it != ']' && *it != '=') attr += *it++; + if (it != end && *it == '=') + { + ++it; + std::string value; + if (it != end && *it == '\'') + { + ++it; + while (it != end && *it != '\'') value += *it++; + if (it != end) ++it; + } + else + { + while (it != end && *it != ']') value += *it++; + } + if (it != end) ++it; + return findNode(it, end, findElement(attr, value, pNode), create); + } + else + { + if (it != end) ++it; + return findAttribute(attr, pNode, create); + } + } + else + { + std::string index; + while (it != end && *it != ']') index += *it++; + if (it != end) ++it; + return findNode(it, end, findElement(Poco::NumberParser::parse(index), pNode, create), create); + } + } + else + { + while (it != end && *it == _delim) ++it; + std::string key; + while (it != end && *it != _delim && *it != '[') key += *it++; + return findNode(it, end, findElement(key, pNode, create), create); + } + } + else return pNode; +} + + +Poco::XML::Node* XMLConfiguration::findElement(const std::string& name, Poco::XML::Node* pNode, bool create) +{ + Poco::XML::Node* pChild = pNode->firstChild(); + while (pChild) + { + if (pChild->nodeType() == Poco::XML::Node::ELEMENT_NODE && pChild->nodeName() == name) + return pChild; + pChild = pChild->nextSibling(); + } + if (create) + { + Poco::AutoPtr<Poco::XML::Element> pElem = pNode->ownerDocument()->createElement(name); + pNode->appendChild(pElem); + return pElem; + } + else return 0; +} + + +Poco::XML::Node* XMLConfiguration::findElement(int index, Poco::XML::Node* pNode, bool create) +{ + Poco::XML::Node* pRefNode = pNode; + if (index > 0) + { + pNode = pNode->nextSibling(); + while (pNode) + { + if (pNode->nodeName() == pRefNode->nodeName()) + { + if (--index == 0) break; + } + pNode = pNode->nextSibling(); + } + } + if (!pNode && create) + { + if (index == 1) + { + Poco::AutoPtr<Poco::XML::Element> pElem = pRefNode->ownerDocument()->createElement(pRefNode->nodeName()); + pRefNode->parentNode()->appendChild(pElem); + return pElem; + } + else throw Poco::InvalidArgumentException("Element index out of range."); + } + return pNode; +} + + +Poco::XML::Node* XMLConfiguration::findElement(const std::string& attr, const std::string& value, Poco::XML::Node* pNode) +{ + Poco::XML::Node* pRefNode = pNode; + Poco::XML::Element* pElem = dynamic_cast<Poco::XML::Element*>(pNode); + if (!(pElem && pElem->getAttribute(attr) == value)) + { + pNode = pNode->nextSibling(); + while (pNode) + { + if (pNode->nodeName() == pRefNode->nodeName()) + { + pElem = dynamic_cast<Poco::XML::Element*>(pNode); + if (pElem && pElem->getAttribute(attr) == value) break; + } + pNode = pNode->nextSibling(); + } + } + return pNode; +} + + +Poco::XML::Node* XMLConfiguration::findAttribute(const std::string& name, Poco::XML::Node* pNode, bool create) +{ + Poco::XML::Node* pResult(0); + Poco::XML::Element* pElem = dynamic_cast<Poco::XML::Element*>(pNode); + if (pElem) + { + pResult = pElem->getAttributeNode(name); + if (!pResult && create) + { + Poco::AutoPtr<Poco::XML::Attr> pAttr = pNode->ownerDocument()->createAttribute(name); + pElem->setAttributeNode(pAttr); + return pAttr; + } + } + return pResult; +} + + +} } // namespace Poco::Util + +#endif // POCO_UTIL_NO_XMLCONFIGURATION |