1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-09-24 21:27:17 +02:00

Major plugin refactor and cleanup.

Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
This commit is contained in:
Sandu Liviu Catalin
2021-01-30 08:51:39 +02:00
parent e0e34b4030
commit 4a6bfc086c
6219 changed files with 1209835 additions and 454916 deletions

View File

@@ -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::Ptr AbstractConfiguration::createView(const std::string& prefix) const
{
return new ConfigurationView(prefix, AbstractConfiguration::Ptr(const_cast<AbstractConfiguration*>(this), true));
}
AbstractConfiguration::Ptr AbstractConfiguration::createView(const std::string& prefix)
{
return new ConfigurationView(prefix, AbstractConfiguration::Ptr(this, true));
}
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 value;
if (getRaw(prop, value))
{
result.append(internalExpand(value));
}
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

557
vendor/POCO/Util/src/Application.cpp vendored Normal file
View File

@@ -0,0 +1,557 @@
//
// 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
#include "Poco/UnicodeConverter.h"
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);
_pConfig->add(new MapConfiguration, PRIO_APPLICATION, true);
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(_WIN32)
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 (auto& pSub: _subsystems)
{
_pLogger->debug(std::string("Initializing subsystem: ") + pSub->name());
pSub->initialize(self);
}
_initialized = true;
}
void Application::uninitialize()
{
if (_initialized)
{
for (auto& pSub: _subsystems)
{
_pLogger->debug(std::string("Uninitializing subsystem: ") + pSub->name());
pSub->uninitialize();
}
_initialized = false;
}
}
void Application::reinitialize(Application& self)
{
for (auto& pSub: _subsystems)
{
_pLogger->debug(std::string("Re-initializing subsystem: ") + pSub->name());
pSub->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);
++n;
}
#ifndef POCO_UTIL_NO_INIFILECONFIGURATION
if (findAppConfigFile(appPath.getBaseName(), "ini", confPath))
{
_pConfig->add(new IniFileConfiguration(confPath.toString()), priority, false);
++n;
}
#endif
#ifndef POCO_UTIL_NO_JSONCONFIGURATION
if (findAppConfigFile(appPath.getBaseName(), "json", confPath))
{
_pConfig->add(new JSONConfiguration(confPath.toString()), priority, false);
++n;
}
#endif
#ifndef POCO_UTIL_NO_XMLCONFIGURATION
if (findAppConfigFile(appPath.getBaseName(), "xml", confPath))
{
_pConfig->add(new XMLConfiguration(confPath.toString()), priority, 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);
++n;
}
#ifndef POCO_UTIL_NO_INIFILECONFIGURATION
else if (icompare(ext, "ini") == 0)
{
_pConfig->add(new IniFileConfiguration(confPath.toString()), priority, false);
++n;
}
#endif
#ifndef POCO_UTIL_NO_JSONCONFIGURATION
else if (icompare(ext, "json") == 0)
{
_pConfig->add(new JSONConfiguration(confPath.toString()), priority, false);
++n;
}
#endif
#ifndef POCO_UTIL_NO_XMLCONFIGURATION
else if (icompare(ext, "xml") == 0)
{
_pConfig->add(new XMLConfiguration(confPath.toString()), priority, 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)
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
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 (auto& pSub: _subsystems)
{
pSub->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

View File

@@ -0,0 +1,98 @@
//
// 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::Ptr pConfig):
_fromPrefix(fromPrefix),
_toPrefix(toPrefix),
_pConfig(pConfig)
{
poco_check_ptr (pConfig);
if (!_fromPrefix.empty()) _fromPrefix += '.';
if (!_toPrefix.empty()) _toPrefix += '.';
}
ConfigurationMapper::~ConfigurationMapper()
{
}
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

View File

@@ -0,0 +1,72 @@
//
// 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::Ptr pConfig):
_prefix(prefix),
_pConfig(pConfig)
{
poco_check_ptr (pConfig);
}
ConfigurationView::~ConfigurationView()
{
}
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

View File

@@ -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 (const auto& tok: tokenizer)
{
result.pushDirectory(tok);
}
return result;
}
} } // namespace Poco::Util

296
vendor/POCO/Util/src/HelpFormatter.cpp vendored Normal file
View File

@@ -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 (const auto& opt: _options)
{
auto shortLen = opt.shortName().length();
auto fullLen = opt.fullName().length();
std::size_t n = 0;
if (_unixStyle && shortLen > 0)
{
n += shortLen + shortPrefix().length();
if (opt.takesArgument())
n += opt.argumentName().length() + (opt.argumentRequired() ? 0 : 2);
if (fullLen > 0) n += 2;
}
if (fullLen > 0)
{
n += fullLen + longPrefix().length();
if (opt.takesArgument())
n += 1 + opt.argumentName().length() + (opt.argumentRequired() ? 0 : 2);
}
n += 2;
if (n > indent)
indent = static_cast<int>(n);
}
return indent;
}
void HelpFormatter::formatOptions(std::ostream& ostr) const
{
int optWidth = calcIndent();
for (const auto& opt: _options)
{
formatOption(ostr, opt, optWidth);
if (_indent < optWidth)
{
ostr << '\n' << std::string(_indent, ' ');
formatText(ostr, opt.description(), _indent, _indent);
}
else
{
formatText(ostr, opt.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 (auto ch: text)
{
if (ch == '\n')
{
clearWord(ostr, pos, word, indent);
ostr << '\n';
pos = 0;
while (pos < indent) { ostr << ' '; ++pos; }
}
else if (ch == '\t')
{
clearWord(ostr, pos, word, indent);
if (pos < _width) ++pos;
while (pos < _width && pos % TAB_WIDTH != 0)
{
ostr << ' ';
++pos;
}
}
else if (ch == ' ')
{
clearWord(ostr, pos, word, indent);
if (pos < _width) { ostr << ' '; ++pos; }
}
else
{
if (word.length() == maxWordLen)
{
clearWord(ostr, pos, word, indent);
}
else word += ch;
}
}
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

View File

@@ -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 (const auto& p: _map)
{
if (icompare(p.first, psize, prefix) == 0)
{
std::string subKey;
std::string::size_type end = p.first.find('.', psize);
if (end == std::string::npos)
subKey = p.first.substr(psize);
else
subKey = p.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

54
vendor/POCO/Util/src/IntValidator.cpp vendored Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,185 @@
//
// 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::Ptr pConfig)
{
add(pConfig, highest(), false);
}
void LayeredConfiguration::add(AbstractConfiguration::Ptr pConfig, const std::string& label)
{
add(pConfig, label, highest(), false);
}
void LayeredConfiguration::add(AbstractConfiguration::Ptr pConfig, int priority)
{
add(pConfig, priority, false);
}
void LayeredConfiguration::add(AbstractConfiguration::Ptr pConfig, const std::string& label, int priority)
{
add(pConfig, label, priority, false);
}
void LayeredConfiguration::addWriteable(AbstractConfiguration::Ptr pConfig, int priority)
{
add(pConfig, priority, true);
}
void LayeredConfiguration::add(AbstractConfiguration::Ptr pConfig, int priority, bool writeable)
{
add(pConfig, std::string(), priority, writeable);
}
void LayeredConfiguration::add(AbstractConfiguration::Ptr pConfig, const std::string& label, int priority, bool writeable)
{
ConfigItem item;
item.pConfig = pConfig;
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::Ptr pConfig)
{
for (ConfigList::iterator it = _configs.begin(); it != _configs.end(); ++it)
{
if (it->pConfig == pConfig)
{
_configs.erase(it);
break;
}
}
}
AbstractConfiguration::Ptr LayeredConfiguration::find(const std::string& label) const
{
for (const auto& conf: _configs)
{
if (conf.label == label) return conf.pConfig;
}
return 0;
}
bool LayeredConfiguration::getRaw(const std::string& key, std::string& value) const
{
for (const auto& conf: _configs)
{
if (conf.pConfig->getRaw(key, value)) return true;
}
return false;
}
void LayeredConfiguration::setRaw(const std::string& key, const std::string& value)
{
for (auto& conf: _configs)
{
if (conf.writeable)
{
conf.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 (const auto& conf: _configs)
{
Keys partRange;
conf.pConfig->enumerate(key, partRange);
for (const auto& k: partRange)
{
if (keys.find(k) == keys.end())
{
range.push_back(k);
keys.insert(k);
}
}
}
}
void LayeredConfiguration::removeRaw(const std::string& key)
{
for (auto& conf: _configs)
{
if (conf.writeable)
{
conf.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

View File

@@ -0,0 +1,198 @@
//
// 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/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::Ptr pConfig)
{
poco_check_ptr (pConfig);
AbstractConfiguration::Ptr pFormattersConfig(pConfig->createView("logging.formatters"));
configureFormatters(pFormattersConfig);
AbstractConfiguration::Ptr pChannelsConfig(pConfig->createView("logging.channels"));
configureChannels(pChannelsConfig);
AbstractConfiguration::Ptr pLoggersConfig(pConfig->createView("logging.loggers"));
configureLoggers(pLoggersConfig);
}
void LoggingConfigurator::configureFormatters(AbstractConfiguration::Ptr pConfig)
{
AbstractConfiguration::Keys formatters;
pConfig->keys(formatters);
for (const auto& f: formatters)
{
AutoPtr<AbstractConfiguration> pFormatterConfig(pConfig->createView(f));
AutoPtr<Formatter> pFormatter(createFormatter(pFormatterConfig));
LoggingRegistry::defaultRegistry().registerFormatter(f, pFormatter);
}
}
void LoggingConfigurator::configureChannels(AbstractConfiguration::Ptr pConfig)
{
AbstractConfiguration::Keys channels;
pConfig->keys(channels);
for (const auto& c: channels)
{
AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(c));
AutoPtr<Channel> pChannel = createChannel(pChannelConfig);
LoggingRegistry::defaultRegistry().registerChannel(c, pChannel);
}
for (const auto& c: channels)
{
AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(c));
Channel::Ptr pChannel = LoggingRegistry::defaultRegistry().channelForName(c);
configureChannel(pChannel, pChannelConfig);
}
}
void LoggingConfigurator::configureLoggers(AbstractConfiguration::Ptr pConfig)
{
using LoggerMap = std::map<std::string, AutoPtr<AbstractConfiguration>>;
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 (const auto& l: loggers)
{
AutoPtr<AbstractConfiguration> pLoggerConfig(pConfig->createView(l));
loggerMap[pLoggerConfig->getString("name", "")] = pLoggerConfig;
}
for (const auto& p: loggerMap)
{
configureLogger(p.second);
}
}
Formatter::Ptr LoggingConfigurator::createFormatter(AbstractConfiguration::Ptr pConfig)
{
Formatter::Ptr pFormatter(LoggingFactory::defaultFactory().createFormatter(pConfig->getString("class")));
AbstractConfiguration::Keys props;
pConfig->keys(props);
for (const auto& p: props)
{
if (p != "class")
pFormatter->setProperty(p, pConfig->getString(p));
}
return pFormatter;
}
Channel::Ptr LoggingConfigurator::createChannel(AbstractConfiguration::Ptr pConfig)
{
Channel::Ptr pChannel(LoggingFactory::defaultFactory().createChannel(pConfig->getString("class")));
Channel::Ptr pWrapper(pChannel);
AbstractConfiguration::Keys props;
pConfig->keys(props);
for (const auto& p: props)
{
if (p == "pattern")
{
AutoPtr<Formatter> pPatternFormatter(new PatternFormatter(pConfig->getString(p)));
pWrapper = new FormattingChannel(pPatternFormatter, pChannel);
}
else if (p == "formatter")
{
AutoPtr<FormattingChannel> pFormattingChannel(new FormattingChannel(0, pChannel));
if (pConfig->hasProperty("formatter.class"))
{
AutoPtr<AbstractConfiguration> pFormatterConfig(pConfig->createView(p));
AutoPtr<Formatter> pFormatter(createFormatter(pFormatterConfig));
pFormattingChannel->setFormatter(pFormatter);
}
else pFormattingChannel->setProperty(p, pConfig->getString(p));
pWrapper = pFormattingChannel;
}
}
return pWrapper;
}
void LoggingConfigurator::configureChannel(Channel::Ptr pChannel, AbstractConfiguration::Ptr pConfig)
{
AbstractConfiguration::Keys props;
pConfig->keys(props);
for (const auto& p: props)
{
if (p != "pattern" && p != "formatter" && p != "class")
{
pChannel->setProperty(p, pConfig->getString(p));
}
}
}
void LoggingConfigurator::configureLogger(AbstractConfiguration::Ptr pConfig)
{
Logger& logger = Logger::get(pConfig->getString("name", ""));
AbstractConfiguration::Keys props;
pConfig->keys(props);
for (const auto& p: props)
{
if (p == "channel" && pConfig->hasProperty("channel.class"))
{
AutoPtr<AbstractConfiguration> pChannelConfig(pConfig->createView(p));
AutoPtr<Channel> pChannel(createChannel(pChannelConfig));
configureChannel(pChannel, pChannelConfig);
Logger::setChannel(logger.name(), pChannel);
}
else if (p != "name")
{
Logger::setProperty(logger.name(), p, pConfig->getString(p));
}
}
}
} } // namespace Poco::Util

View File

@@ -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.configPtr());
std::string logger = app.config().getString("application.logger", "Application");
app.setLogger(Logger::get(logger));
}
void LoggingSubsystem::uninitialize()
{
}
} } // namespace Poco::Util

View File

@@ -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 (const auto& p: _map)
{
config.setString(p.first, p.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 (const auto& p: _map)
{
if (p.first.compare(0, psize, prefix) == 0)
{
std::string subKey;
std::string::size_type end = p.first.find('.', psize);
if (end == std::string::npos)
subKey = p.first.substr(psize);
else
subKey = p.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

292
vendor/POCO/Util/src/Option.cpp vendored Normal file
View File

@@ -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

37
vendor/POCO/Util/src/OptionCallback.cpp vendored Normal file
View File

@@ -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

View File

@@ -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

159
vendor/POCO/Util/src/OptionProcessor.cpp vendored Normal file
View File

@@ -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 (const auto& opt: _options)
{
if (opt.required() && _specifiedOptions.find(opt.fullName()) == _specifiedOptions.end())
throw MissingOptionException(opt.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

122
vendor/POCO/Util/src/OptionSet.cpp vendored Normal file
View File

@@ -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 (const auto& opt: _options)
{
if ((matchShort && opt.matchesShort(name)) || (!matchShort && opt.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 (const auto& opt: _options)
{
if ((matchShort && opt.matchesShort(name)) || (!matchShort && opt.matchesPartial(name)))
{
if (!pOption)
{
pOption = &opt;
if (!matchShort && opt.matchesFull(name))
break;
}
else if (!matchShort && opt.matchesFull(name))
{
pOption = &opt;
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

View File

@@ -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 (auto ch: it->second)
{
switch (ch)
{
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 << ch;
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

View File

@@ -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

View File

@@ -0,0 +1,722 @@
//
// 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
#include "Poco/UnicodeConverter.h"
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);
}
void ServerApplication::ServiceMain(DWORD argc, LPWSTR* argv)
{
ServerApplication& app = static_cast<ServerApplication&>(Application::instance());
app.config().setBool("application.runAsService", true);
_serviceStatusHandle = RegisterServiceCtrlHandlerW(L"", ServiceControlHandler);
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
{
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);
_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;
}
}
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;
}
}
bool ServerApplication::isService()
{
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;
}
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();
}
int ServerApplication::run(int argc, wchar_t** argv)
{
try
{
init(argc, argv);
}
catch (Exception& exc)
{
logger().log(exc);
return EXIT_CONFIG;
}
return run();
}
#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 (const auto& arg: args)
{
if (arg == "--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 (const auto ch: value)
{
mask *= 8;
if (ch >= '0' && ch <= '7')
mask += ch - '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

44
vendor/POCO/Util/src/Subsystem.cpp vendored Normal file
View File

@@ -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

View File

@@ -0,0 +1,211 @@
//
// 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

351
vendor/POCO/Util/src/Timer.cpp vendored Normal file
View File

@@ -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

40
vendor/POCO/Util/src/TimerTask.cpp vendored Normal file
View File

@@ -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

32
vendor/POCO/Util/src/Validator.cpp vendored Normal file
View File

@@ -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

View File

@@ -0,0 +1,144 @@
//
// WinRegistryConfiguration.cpp
//
// Library: Util
// Package: Windows
// Module: WinRegistryConfiguration
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Util/WinRegistryConfiguration.h"
#include "Poco/Util/WinRegistryKey.h"
#include "Poco/NumberFormatter.h"
#include "Poco/NumberParser.h"
#include "Poco/Exception.h"
namespace Poco {
namespace Util {
WinRegistryConfiguration::WinRegistryConfiguration(const std::string& rootPath, REGSAM extraSam): _rootPath(rootPath), _extraSam(extraSam)
{
// rootPath must end with backslash
if (!_rootPath.empty())
{
if (_rootPath[_rootPath.length() - 1] != '\\')
_rootPath += '\\';
}
}
WinRegistryConfiguration::~WinRegistryConfiguration()
{
}
bool WinRegistryConfiguration::getRaw(const std::string& key, std::string& value) const
{
std::string keyName;
std::string fullPath = _rootPath + convertToRegFormat(key, keyName);
WinRegistryKey aKey(fullPath, true, _extraSam);
bool exists = aKey.exists(keyName);
if (exists)
{
WinRegistryKey::Type type = aKey.type(keyName);
switch (type)
{
case WinRegistryKey::REGT_STRING:
value = aKey.getString(keyName);
break;
case WinRegistryKey::REGT_STRING_EXPAND:
value = aKey.getStringExpand(keyName);
break;
case WinRegistryKey::REGT_BINARY:
{
std::vector<char> tmp = aKey.getBinary(keyName);
value.assign(tmp.begin(), tmp.end());
}
break;
case WinRegistryKey::REGT_DWORD:
value = Poco::NumberFormatter::format(aKey.getInt(keyName));
break;
#if defined(POCO_HAVE_INT64)
case WinRegistryKey::REGT_QWORD:
value = Poco::NumberFormatter::format(aKey.getInt64(keyName));
break;
#endif
default:
exists = false;
}
}
return exists;
}
void WinRegistryConfiguration::setRaw(const std::string& key, const std::string& value)
{
std::string keyName;
std::string fullPath = _rootPath + convertToRegFormat(key, keyName);
WinRegistryKey aKey(fullPath, false, _extraSam);
aKey.setString(keyName, value);
}
void WinRegistryConfiguration::enumerate(const std::string& key, Keys& range) const
{
std::string keyName;
std::string fullPath = _rootPath + convertToRegFormat(key, keyName);
if (fullPath.empty())
{
// return all root level keys
#if defined(_WIN32_WCE)
range.push_back("HKEY_CLASSES_ROOT");
range.push_back("HKEY_CURRENT_USER");
range.push_back("HKEY_LOCAL_MACHINE");
range.push_back("HKEY_USERS");
#else
range.push_back("HKEY_CLASSES_ROOT");
range.push_back("HKEY_CURRENT_CONFIG");
range.push_back("HKEY_CURRENT_USER");
range.push_back("HKEY_LOCAL_MACHINE");
range.push_back("HKEY_PERFORMANCE_DATA");
range.push_back("HKEY_USERS");
#endif
}
else
{
fullPath += '\\';
fullPath += keyName;
WinRegistryKey aKey(fullPath, true, _extraSam);
aKey.values(range);
aKey.subKeys(range);
}
}
void WinRegistryConfiguration::removeRaw(const std::string& key)
{
throw Poco::NotImplementedException("Removing a key in a WinRegistryConfiguration");
}
std::string WinRegistryConfiguration::convertToRegFormat(const std::string& key, std::string& value) const
{
std::size_t pos = key.rfind('.');
if (pos == std::string::npos)
{
value = key;
return std::string();
}
std::string prefix(key.substr(0,pos));
value = key.substr(pos + 1);
Poco::translateInPlace(prefix, ".", "\\");
return prefix;
}
} } // namespace Poco::Util

509
vendor/POCO/Util/src/WinRegistryKey.cpp vendored Normal file
View File

@@ -0,0 +1,509 @@
//
// WinRegistryKey.cpp
//
// Library: Util
// Package: Windows
// Module: WinRegistryKey
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Util/WinRegistryKey.h"
#include "Poco/Exception.h"
#include "Poco/Buffer.h"
#include "Poco/UnicodeConverter.h"
using Poco::SystemException;
using Poco::NotFoundException;
using Poco::InvalidArgumentException;
namespace Poco {
namespace Util {
namespace
{
class AutoHandle
{
public:
AutoHandle(HMODULE h):
_h(h)
{
}
~AutoHandle()
{
FreeLibrary(_h);
}
HMODULE handle()
{
return _h;
}
private:
HMODULE _h;
};
}
WinRegistryKey::WinRegistryKey(const std::string& key, bool readOnly, REGSAM extraSam):
_hKey(0),
_readOnly(readOnly),
_extraSam(extraSam)
{
std::string::size_type pos = key.find('\\');
if (pos != std::string::npos)
{
std::string rootKey = key.substr(0, pos);
_hRootKey = handleFor(rootKey);
_subKey = key.substr(pos + 1);
}
else throw InvalidArgumentException("Not a valid registry key", key);
}
WinRegistryKey::WinRegistryKey(HKEY hRootKey, const std::string& subKey, bool readOnly, REGSAM extraSam):
_hRootKey(hRootKey),
_subKey(subKey),
_hKey(0),
_readOnly(readOnly),
_extraSam(extraSam)
{
}
WinRegistryKey::~WinRegistryKey()
{
close();
}
void WinRegistryKey::setString(const std::string& name, const std::string& value)
{
open();
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
std::wstring uvalue;
Poco::UnicodeConverter::toUTF16(value, uvalue);
if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_SZ, (CONST BYTE*) uvalue.c_str(), (DWORD) (uvalue.size() + 1)*sizeof(wchar_t)) != ERROR_SUCCESS)
handleSetError(name);
}
std::string WinRegistryKey::getString(const std::string& name)
{
open();
DWORD type;
DWORD size;
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_LINK))
throw NotFoundException(key(name));
if (size > 0)
{
DWORD len = size/2;
Poco::Buffer<wchar_t> buffer(len + 1);
RegQueryValueExW(_hKey, uname.c_str(), NULL, NULL, (BYTE*) buffer.begin(), &size);
buffer[len] = 0;
std::wstring uresult(buffer.begin());
std::string result;
Poco::UnicodeConverter::toUTF8(uresult, result);
return result;
}
return std::string();
}
void WinRegistryKey::setStringExpand(const std::string& name, const std::string& value)
{
open();
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
std::wstring uvalue;
Poco::UnicodeConverter::toUTF16(value, uvalue);
if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_EXPAND_SZ, (CONST BYTE*) uvalue.c_str(), (DWORD) (uvalue.size() + 1)*sizeof(wchar_t)) != ERROR_SUCCESS)
handleSetError(name);
}
std::string WinRegistryKey::getStringExpand(const std::string& name)
{
open();
DWORD type;
DWORD size;
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_LINK))
throw NotFoundException(key(name));
if (size > 0)
{
DWORD len = size/2;
Poco::Buffer<wchar_t> buffer(len + 1);
RegQueryValueExW(_hKey, uname.c_str(), NULL, NULL, (BYTE*) buffer.begin(), &size);
buffer[len] = 0;
#if !defined(_WIN32_WCE)
wchar_t temp;
DWORD expSize = ExpandEnvironmentStringsW(buffer.begin(), &temp, 1);
Poco::Buffer<wchar_t> expBuffer(expSize);
ExpandEnvironmentStringsW(buffer.begin(), expBuffer.begin(), expSize);
std::string result;
UnicodeConverter::toUTF8(expBuffer.begin(), result);
#else
std::string result;
UnicodeConverter::toUTF8(buffer.begin(), result);
#endif
return result;
}
return std::string();
}
void WinRegistryKey::setBinary( const std::string& name, const std::vector<char>& value )
{
open();
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_BINARY, (CONST BYTE*) &value[0], (DWORD) value.size()) != ERROR_SUCCESS)
handleSetError(name);
}
std::vector<char> WinRegistryKey::getBinary( const std::string& name )
{
open();
DWORD type;
DWORD size;
std::vector<char> result;
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || type != REG_BINARY)
throw NotFoundException(key(name));
if (size > 0)
{
result.resize(size);
RegQueryValueExW(_hKey, uname.c_str(), NULL, NULL, (BYTE*) &result[0], &size);
}
return result;
}
void WinRegistryKey::setInt(const std::string& name, int value)
{
open();
DWORD data = value;
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_DWORD, (CONST BYTE*) &data, sizeof(data)) != ERROR_SUCCESS)
handleSetError(name);
}
int WinRegistryKey::getInt(const std::string& name)
{
open();
DWORD type;
DWORD data;
DWORD size = sizeof(data);
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || (type != REG_DWORD && type != REG_DWORD_BIG_ENDIAN))
throw NotFoundException(key(name));
return data;
}
#if defined(POCO_HAVE_INT64)
void WinRegistryKey::setInt64(const std::string& name, Poco::Int64 value)
{
open();
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_QWORD, (CONST BYTE*) &value, sizeof(value)) != ERROR_SUCCESS)
handleSetError(name);
}
Poco::Int64 WinRegistryKey::getInt64(const std::string& name)
{
open();
DWORD type;
Poco::Int64 data;
DWORD size = sizeof(data);
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || type != REG_QWORD)
throw NotFoundException(key(name));
return data;
}
#endif // POCO_HAVE_INT64
void WinRegistryKey::deleteValue(const std::string& name)
{
open();
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegDeleteValueW(_hKey, uname.c_str()) != ERROR_SUCCESS)
throw NotFoundException(key(name));
}
void WinRegistryKey::deleteKey()
{
Keys keys;
subKeys(keys);
close();
for (const auto& k: keys)
{
std::string subKey(_subKey);
subKey += "\\";
subKey += k;
WinRegistryKey subRegKey(_hRootKey, subKey, _readOnly, _extraSam);
subRegKey.deleteKey();
}
// NOTE: RegDeleteKeyEx is only available on Windows XP 64-bit SP3, Windows Vista or later.
// We cannot call it directly as this would prevent the code running on Windows XP 32-bit.
// Therefore, if we need to call RegDeleteKeyEx (_extraSam != 0) we need to check for
// its existence in ADVAPI32.DLL and call it indirectly.
std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
#if !defined(_WIN32_WCE)
typedef LONG (WINAPI *RegDeleteKeyExWFunc)(HKEY hKey, const wchar_t* lpSubKey, REGSAM samDesired, DWORD Reserved);
if (_extraSam != 0)
{
AutoHandle advAPI32(LoadLibraryW(L"ADVAPI32.DLL"));
if (advAPI32.handle())
{
RegDeleteKeyExWFunc pRegDeleteKeyExW = reinterpret_cast<RegDeleteKeyExWFunc>(GetProcAddress(advAPI32.handle() , "RegDeleteKeyExW"));
if (pRegDeleteKeyExW)
{
if ((*pRegDeleteKeyExW)(_hRootKey, usubKey.c_str(), _extraSam, 0) != ERROR_SUCCESS)
throw NotFoundException(key());
return;
}
}
}
#endif
if (RegDeleteKeyW(_hRootKey, usubKey.c_str()) != ERROR_SUCCESS)
throw NotFoundException(key());
}
bool WinRegistryKey::exists()
{
HKEY hKey;
std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &hKey) == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return true;
}
return false;
}
WinRegistryKey::Type WinRegistryKey::type(const std::string& name)
{
open();
DWORD type = REG_NONE;
DWORD size;
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS)
throw NotFoundException(key(name));
Type aType = (Type)type;
return aType;
}
bool WinRegistryKey::exists(const std::string& name)
{
bool exists = false;
HKEY hKey;
std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &hKey) == ERROR_SUCCESS)
{
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
exists = RegQueryValueExW(hKey, uname.c_str(), NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
RegCloseKey(hKey);
}
return exists;
}
void WinRegistryKey::open()
{
if (!_hKey)
{
std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
if (_readOnly)
{
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &_hKey) != ERROR_SUCCESS)
throw NotFoundException("Cannot open registry key: ", key());
}
else
{
if (RegCreateKeyExW(_hRootKey, usubKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE | _extraSam, NULL, &_hKey, NULL) != ERROR_SUCCESS)
throw SystemException("Cannot open registry key: ", key());
}
}
}
void WinRegistryKey::close()
{
if (_hKey)
{
RegCloseKey(_hKey);
_hKey = 0;
}
}
std::string WinRegistryKey::key() const
{
std::string result;
if (_hRootKey == HKEY_CLASSES_ROOT)
result = "HKEY_CLASSES_ROOT";
#if defined(HKEY_CURRENT_CONFIG)
else if (_hRootKey == HKEY_CURRENT_CONFIG)
result = "HKEY_CURRENT_CONFIG";
#endif
else if (_hRootKey == HKEY_CURRENT_USER)
result = "HKEY_CURRENT_USER";
else if (_hRootKey == HKEY_LOCAL_MACHINE)
result = "HKEY_LOCAL_MACHINE";
else if (_hRootKey == HKEY_USERS)
result = "HKEY_USERS";
#if defined(HKEY_PERFORMANCE_DATA)
else if (_hRootKey == HKEY_PERFORMANCE_DATA)
result = "HKEY_PERFORMANCE_DATA";
#endif
else
result = "(UNKNOWN)";
result += '\\';
result += _subKey;
return result;
}
std::string WinRegistryKey::key(const std::string& valueName) const
{
std::string result = key();
if (!valueName.empty())
{
result += '\\';
result += valueName;
}
return result;
}
HKEY WinRegistryKey::handle()
{
open();
return _hKey;
}
HKEY WinRegistryKey::handleFor(const std::string& rootKey)
{
if (rootKey == "HKEY_CLASSES_ROOT")
return HKEY_CLASSES_ROOT;
#if defined(HKEY_CURRENT_CONFIG)
else if (rootKey == "HKEY_CURRENT_CONFIG")
return HKEY_CURRENT_CONFIG;
#endif
else if (rootKey == "HKEY_CURRENT_USER")
return HKEY_CURRENT_USER;
else if (rootKey == "HKEY_LOCAL_MACHINE")
return HKEY_LOCAL_MACHINE;
else if (rootKey == "HKEY_USERS")
return HKEY_USERS;
#if defined(HKEY_PERFORMANCE_DATA)
else if (rootKey == "HKEY_PERFORMANCE_DATA")
return HKEY_PERFORMANCE_DATA;
#endif
else
throw InvalidArgumentException("Not a valid root key", rootKey);
}
void WinRegistryKey::handleSetError(const std::string& name)
{
std::string msg = "Failed to set registry value";
throw SystemException(msg, key(name));
}
void WinRegistryKey::subKeys(WinRegistryKey::Keys& keys)
{
open();
DWORD subKeyCount = 0;
DWORD valueCount = 0;
if (RegQueryInfoKey(_hKey, NULL, NULL, NULL, &subKeyCount, NULL, NULL, &valueCount, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
return;
wchar_t buf[256];
DWORD bufSize = sizeof(buf)/sizeof(wchar_t);
for (DWORD i = 0; i< subKeyCount; ++i)
{
if (RegEnumKeyExW(_hKey, i, buf, &bufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
std::wstring uname(buf);
std::string name;
Poco::UnicodeConverter::toUTF8(uname, name);
keys.push_back(name);
}
bufSize = sizeof(buf)/sizeof(wchar_t);
}
}
void WinRegistryKey::values(WinRegistryKey::Values& vals)
{
open();
DWORD valueCount = 0;
if (RegQueryInfoKey(_hKey, NULL, NULL, NULL, NULL, NULL, NULL, &valueCount, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
return ;
wchar_t buf[256];
DWORD bufSize = sizeof(buf)/sizeof(wchar_t);
for (DWORD i = 0; i< valueCount; ++i)
{
if (RegEnumValueW(_hKey, i, buf, &bufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
std::wstring uname(buf);
std::string name;
Poco::UnicodeConverter::toUTF8(uname, name);
vals.push_back(name);
}
bufSize = sizeof(buf)/sizeof(wchar_t);
}
}
} } // namespace Poco::Util

426
vendor/POCO/Util/src/WinService.cpp vendored Normal file
View File

@@ -0,0 +1,426 @@
//
// WinService.cpp
//
// Library: Util
// Package: Windows
// Module: WinService
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#if !defined(_WIN32_WCE)
#include "Poco/Util/WinService.h"
#include "Poco/Util/WinRegistryKey.h"
#include "Poco/Thread.h"
#include "Poco/Exception.h"
#include "Poco/UnicodeConverter.h"
using Poco::Thread;
using Poco::SystemException;
using Poco::NotFoundException;
using Poco::OutOfMemoryException;
namespace Poco {
namespace Util {
const int WinService::STARTUP_TIMEOUT = 30000;
const std::string WinService::REGISTRY_KEY("SYSTEM\\CurrentControlSet\\Services\\");
const std::string WinService::REGISTRY_DESCRIPTION("Description");
WinService::WinService(const std::string& name):
_name(name),
_svcHandle(0)
{
_scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!_scmHandle) throw SystemException("cannot open Service Control Manager");
}
WinService::WinService(SC_HANDLE scmHandle, const std::string& name):
_scmHandle(scmHandle),
_name(name),
_svcHandle(0)
{
if (!_scmHandle) throw SystemException("Service Control Manager not connected");
}
WinService::~WinService()
{
close();
CloseServiceHandle(_scmHandle);
}
const std::string& WinService::name() const
{
return _name;
}
std::string WinService::displayName() const
{
POCO_LPQUERY_SERVICE_CONFIG pSvcConfig = config();
std::wstring udispName(pSvcConfig->lpDisplayName);
std::string dispName;
Poco::UnicodeConverter::toUTF8(udispName, dispName);
LocalFree(pSvcConfig);
return dispName;
}
std::string WinService::path() const
{
POCO_LPQUERY_SERVICE_CONFIG pSvcConfig = config();
std::wstring upath(pSvcConfig->lpBinaryPathName);
std::string path;
UnicodeConverter::toUTF8(upath, path);
LocalFree(pSvcConfig);
return path;
}
void WinService::registerService(const std::string& path, const std::string& displayName)
{
close();
std::wstring uname;
Poco::UnicodeConverter::toUTF16(_name, uname);
std::wstring udisplayName;
Poco::UnicodeConverter::toUTF16(displayName, udisplayName);
std::wstring upath;
Poco::UnicodeConverter::toUTF16(path, upath);
_svcHandle = CreateServiceW(
_scmHandle,
uname.c_str(),
udisplayName.c_str(),
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
upath.c_str(),
NULL, NULL, NULL, NULL, NULL);
if (!_svcHandle)
throw SystemException("cannot register service", _name);
}
void WinService::registerService(const std::string& path)
{
registerService(path, _name);
}
void WinService::unregisterService()
{
open();
if (!DeleteService(_svcHandle))
throw SystemException("cannot unregister service", _name);
close();
}
bool WinService::isRegistered() const
{
return tryOpen();
}
bool WinService::isRunning() const
{
open();
SERVICE_STATUS ss;
if (!QueryServiceStatus(_svcHandle, &ss))
throw SystemException("cannot query service status", _name);
return ss.dwCurrentState == SERVICE_RUNNING;
}
bool WinService::isStopped() const
{
open();
SERVICE_STATUS ss;
if (!QueryServiceStatus(_svcHandle, &ss))
throw SystemException("cannot query service status", _name);
return ss.dwCurrentState == SERVICE_STOPPED;
}
void WinService::start()
{
open();
if (!StartService(_svcHandle, 0, NULL))
throw SystemException("cannot start service", _name);
SERVICE_STATUS svcStatus;
long msecs = 0;
while (msecs < STARTUP_TIMEOUT)
{
if (!QueryServiceStatus(_svcHandle, &svcStatus)) break;
if (svcStatus.dwCurrentState != SERVICE_START_PENDING) break;
Thread::sleep(250);
msecs += 250;
}
if (!QueryServiceStatus(_svcHandle, &svcStatus))
throw SystemException("cannot query status of starting service", _name);
else if (svcStatus.dwCurrentState != SERVICE_RUNNING)
throw SystemException("service failed to start within a reasonable time", _name);
}
void WinService::stop()
{
open();
SERVICE_STATUS svcStatus;
if (!ControlService(_svcHandle, SERVICE_CONTROL_STOP, &svcStatus))
throw SystemException("cannot stop service", _name);
}
void WinService::setStartup(WinService::Startup startup)
{
open();
DWORD startType;
switch (startup)
{
case SVC_AUTO_START:
startType = SERVICE_AUTO_START;
break;
case SVC_MANUAL_START:
startType = SERVICE_DEMAND_START;
break;
case SVC_DISABLED:
startType = SERVICE_DISABLED;
break;
default:
startType = SERVICE_NO_CHANGE;
}
if (!ChangeServiceConfig(_svcHandle, SERVICE_NO_CHANGE, startType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
{
throw SystemException("cannot change service startup mode");
}
}
WinService::Startup WinService::getStartup() const
{
POCO_LPQUERY_SERVICE_CONFIG pSvcConfig = config();
Startup result;
switch (pSvcConfig->dwStartType)
{
case SERVICE_AUTO_START:
case SERVICE_BOOT_START:
case SERVICE_SYSTEM_START:
result = SVC_AUTO_START;
break;
case SERVICE_DEMAND_START:
result = SVC_MANUAL_START;
break;
case SERVICE_DISABLED:
result = SVC_DISABLED;
break;
default:
poco_debugger();
result = SVC_MANUAL_START;
}
LocalFree(pSvcConfig);
return result;
}
void WinService::setFailureActions(FailureActionVector failureActions, const std::string& command, const std::string& rebootMessage)
{
if (failureActions.size() > 3) {
throw InvalidArgumentException{ "Only 0-3 Failure Actions are supported" };
}
open();
auto actions = new SC_ACTION[failureActions.size()];
SERVICE_FAILURE_ACTIONSW ac;
ac.lpCommand = NULL;
ac.lpRebootMsg = NULL;
std::wstring urebootMessage;
Poco::UnicodeConverter::toUTF16(rebootMessage, urebootMessage);
std::vector<wchar_t> rebootMessageVector{ urebootMessage.begin(), urebootMessage.end() };
rebootMessageVector.push_back('\0');
std::wstring uComamnd;
Poco::UnicodeConverter::toUTF16(command, uComamnd);
std::vector<wchar_t> commandVector{ uComamnd.begin(), uComamnd.end() };
commandVector.push_back('\0');
for (auto i = 0; i < failureActions.size(); i++)
{
switch (failureActions[i].type)
{
case SVC_REBOOT:
actions[i].Type = SC_ACTION_REBOOT;
actions[i].Delay = failureActions[i].delay;
ac.lpRebootMsg = &rebootMessageVector[0];
break;
case SVC_RESTART:
actions[i].Type = SC_ACTION_RESTART;
actions[i].Delay = failureActions[i].delay;
break;
case SVC_RUN_COMMAND:
actions[i].Type = SC_ACTION_RUN_COMMAND;
actions[i].Delay = failureActions[i].delay;
ac.lpCommand = &commandVector[0];
break;
default:
actions[i].Type = SC_ACTION_NONE;
actions[i].Delay = 0;
break;
}
}
ac.dwResetPeriod = 0;
ac.cActions = failureActions.size();
ac.lpsaActions = actions;
if (!ChangeServiceConfig2W(_svcHandle, SERVICE_CONFIG_FAILURE_ACTIONS, &ac))
{
delete[] actions;
throw SystemException("cannot configure service", _name);
}
delete[] actions;
}
WinService::FailureActionTypeVector WinService::getFailureActions() const {
open();
int size = 4096;
DWORD bytesNeeded;
POCO_LPSERVICE_FAILURE_ACTION pSvcFailureAction = (POCO_LPSERVICE_FAILURE_ACTION)LocalAlloc(LPTR, size);
if (!pSvcFailureAction) throw OutOfMemoryException("cannot allocate service failure action buffer");
try {
while (!QueryServiceConfig2W(_svcHandle, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)pSvcFailureAction, size, &bytesNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
LocalFree(pSvcFailureAction);
size = bytesNeeded;
pSvcFailureAction = (POCO_LPSERVICE_FAILURE_ACTION)LocalAlloc(LPTR, size);
} else throw SystemException("cannot query service configuration", _name);
}
}
catch (...)
{
LocalFree(pSvcFailureAction);
throw;
}
FailureActionTypeVector result(3, SVC_NONE);
for (auto i = 0; i < pSvcFailureAction->cActions; i++)
{
switch (pSvcFailureAction->lpsaActions->Type)
{
case SC_ACTION_NONE:
result[i] = SVC_NONE;
break;
case SC_ACTION_RESTART:
result[i] = SVC_RESTART;
break;
case SC_ACTION_REBOOT:
result[i] = SVC_REBOOT;
break;
case SC_ACTION_RUN_COMMAND:
result[i] = SVC_RUN_COMMAND;
break;
default:
result[i] = SVC_NONE;
}
++pSvcFailureAction->lpsaActions;
}
LocalFree(pSvcFailureAction);
return result;
}
void WinService::setDescription(const std::string& description)
{
std::string key(REGISTRY_KEY);
key += _name;
WinRegistryKey regKey(HKEY_LOCAL_MACHINE, key);
regKey.setString(REGISTRY_DESCRIPTION, description);
}
std::string WinService::getDescription() const
{
std::string key(REGISTRY_KEY);
key += _name;
WinRegistryKey regKey(HKEY_LOCAL_MACHINE, key, true);
return regKey.getString(REGISTRY_DESCRIPTION);
}
void WinService::open() const
{
if (!tryOpen())
throw NotFoundException("service does not exist", _name);
}
bool WinService::tryOpen() const
{
if (!_svcHandle)
{
std::wstring uname;
Poco::UnicodeConverter::toUTF16(_name, uname);
_svcHandle = OpenServiceW(_scmHandle, uname.c_str(), SERVICE_ALL_ACCESS);
}
return _svcHandle != 0;
}
void WinService::close() const
{
if (_svcHandle)
{
CloseServiceHandle(_svcHandle);
_svcHandle = 0;
}
}
POCO_LPQUERY_SERVICE_CONFIG WinService::config() const
{
open();
int size = 4096;
DWORD bytesNeeded;
POCO_LPQUERY_SERVICE_CONFIG pSvcConfig = (POCO_LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, size);
if (!pSvcConfig) throw OutOfMemoryException("cannot allocate service config buffer");
try
{
while (!QueryServiceConfigW(_svcHandle, pSvcConfig, size, &bytesNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
LocalFree(pSvcConfig);
size = bytesNeeded;
pSvcConfig = (POCO_LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, size);
}
else throw SystemException("cannot query service configuration", _name);
}
}
catch (...)
{
LocalFree(pSvcConfig);
throw;
}
return pSvcConfig;
}
} } // namespace Poco::Util
#endif // !defined(_WIN32_WCE)

View File

@@ -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