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:
536
vendor/POCO/Util/src/AbstractConfiguration.cpp
vendored
Normal file
536
vendor/POCO/Util/src/AbstractConfiguration.cpp
vendored
Normal 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
557
vendor/POCO/Util/src/Application.cpp
vendored
Normal 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
|
98
vendor/POCO/Util/src/ConfigurationMapper.cpp
vendored
Normal file
98
vendor/POCO/Util/src/ConfigurationMapper.cpp
vendored
Normal 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
|
72
vendor/POCO/Util/src/ConfigurationView.cpp
vendored
Normal file
72
vendor/POCO/Util/src/ConfigurationView.cpp
vendored
Normal 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
|
127
vendor/POCO/Util/src/FilesystemConfiguration.cpp
vendored
Normal file
127
vendor/POCO/Util/src/FilesystemConfiguration.cpp
vendored
Normal 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
296
vendor/POCO/Util/src/HelpFormatter.cpp
vendored
Normal 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
|
190
vendor/POCO/Util/src/IniFileConfiguration.cpp
vendored
Normal file
190
vendor/POCO/Util/src/IniFileConfiguration.cpp
vendored
Normal 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
54
vendor/POCO/Util/src/IntValidator.cpp
vendored
Normal 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
|
386
vendor/POCO/Util/src/JSONConfiguration.cpp
vendored
Normal file
386
vendor/POCO/Util/src/JSONConfiguration.cpp
vendored
Normal 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
|
185
vendor/POCO/Util/src/LayeredConfiguration.cpp
vendored
Normal file
185
vendor/POCO/Util/src/LayeredConfiguration.cpp
vendored
Normal 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
|
198
vendor/POCO/Util/src/LoggingConfigurator.cpp
vendored
Normal file
198
vendor/POCO/Util/src/LoggingConfigurator.cpp
vendored
Normal 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
|
58
vendor/POCO/Util/src/LoggingSubsystem.cpp
vendored
Normal file
58
vendor/POCO/Util/src/LoggingSubsystem.cpp
vendored
Normal 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
|
122
vendor/POCO/Util/src/MapConfiguration.cpp
vendored
Normal file
122
vendor/POCO/Util/src/MapConfiguration.cpp
vendored
Normal 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
292
vendor/POCO/Util/src/Option.cpp
vendored
Normal 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
37
vendor/POCO/Util/src/OptionCallback.cpp
vendored
Normal 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
|
35
vendor/POCO/Util/src/OptionException.cpp
vendored
Normal file
35
vendor/POCO/Util/src/OptionException.cpp
vendored
Normal 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
159
vendor/POCO/Util/src/OptionProcessor.cpp
vendored
Normal 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
122
vendor/POCO/Util/src/OptionSet.cpp
vendored
Normal 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
|
190
vendor/POCO/Util/src/PropertyFileConfiguration.cpp
vendored
Normal file
190
vendor/POCO/Util/src/PropertyFileConfiguration.cpp
vendored
Normal 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
|
47
vendor/POCO/Util/src/RegExpValidator.cpp
vendored
Normal file
47
vendor/POCO/Util/src/RegExpValidator.cpp
vendored
Normal 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
|
722
vendor/POCO/Util/src/ServerApplication.cpp
vendored
Normal file
722
vendor/POCO/Util/src/ServerApplication.cpp
vendored
Normal 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
44
vendor/POCO/Util/src/Subsystem.cpp
vendored
Normal 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
|
211
vendor/POCO/Util/src/SystemConfiguration.cpp
vendored
Normal file
211
vendor/POCO/Util/src/SystemConfiguration.cpp
vendored
Normal 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
351
vendor/POCO/Util/src/Timer.cpp
vendored
Normal 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
40
vendor/POCO/Util/src/TimerTask.cpp
vendored
Normal 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
32
vendor/POCO/Util/src/Validator.cpp
vendored
Normal 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
|
144
vendor/POCO/Util/src/WinRegistryConfiguration.cpp
vendored
Normal file
144
vendor/POCO/Util/src/WinRegistryConfiguration.cpp
vendored
Normal 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
509
vendor/POCO/Util/src/WinRegistryKey.cpp
vendored
Normal 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
426
vendor/POCO/Util/src/WinService.cpp
vendored
Normal 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)
|
479
vendor/POCO/Util/src/XMLConfiguration.cpp
vendored
Normal file
479
vendor/POCO/Util/src/XMLConfiguration.cpp
vendored
Normal 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
|
Reference in New Issue
Block a user