diff --git a/README.md b/README.md
index 77c4e641..44005d46 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,3 @@
-# ARK-Server-API
-ArkApi is a plugin which allows you to create your own server-side plugins for ARK using C++ language.
+# PLEASE READ:
-## Download
-http://arkserverapi.com/resources/ark-server-api.4/
-
-[Plugins](http://arkserverapi.com/resources/categories/ark-server-plugins.3/)
-
-## Compilation
-Requirements:
-* Visual Studio 2017
+The GITHUB REPO HAS BEEN MOVED TO https://github.com/ServersHub
diff --git a/build.bat b/build.bat
new file mode 100644
index 00000000..eca0bef0
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,10 @@
+@echo off
+chcp 65001
+echo Compiling ARK-Server-API...
+echo.
+
+"D:\Program Files\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" version.sln /p:Configuration=Ark /p:Platform=x64 /p:PlatformToolset=v142
+
+echo.
+echo Compilation completed!
+echo Output file: out_lib\ArkApi.lib
\ No newline at end of file
diff --git a/config.json b/config.json
index ded527bc..90c32236 100644
--- a/config.json
+++ b/config.json
@@ -1,102 +1,7 @@
-{
- "settings":{
- "AutomaticPluginReloading":false,
+{
+ "settings":{
+ "AutomaticPluginReloading":true,
"AutomaticPluginReloadSeconds":5,
"SaveWorldBeforePluginReload":true
- },
- "structures":[
- "UWorld",
- "AController",
- "AShooterPlayerController",
- "APlayerController",
- "UCheatManager",
- "UShooterCheatManager",
- "AShooterGameMode",
- "AGameMode",
- "UPlayer",
- "APrimalTargetableActor",
- "APrimalStructure",
- "APrimalStructureDoor",
- "FTribeData",
- "FTribeWar",
- "FTribeRankGroup",
- "ACharacter",
- "AShooterCharacter",
- "APrimalCharacter",
- "AActor",
- "APlayerState",
- "AShooterPlayerState",
- "UPrimalPlayerData",
- "FPrimalPlayerDataStruct",
- "FPrimalPersistentCharacterStatsStruct",
- "UPrimalInventoryComponent",
- "UPrimalItem",
- "FItemNetInfo",
- "APrimalDinoCharacter",
- "USceneComponent",
- "UPrimalCharacterStatusComponent",
- "FWeakObjectPtr",
- "FDamageEvent",
- "FHitResult",
- "AGameState",
- "AShooterGameState",
- "AShooterWeapon",
- "UClass",
- "UStruct",
- "UProperty",
- "UObjectBaseUtility",
- "UNumericProperty",
- "URCONServer",
- "RCONClientConnection",
- "RCONPacket",
- "FUniqueNetIdSteam",
- "UGameplayStatics",
- "UObject",
- "UObjectBase",
- "FString",
- "AShooterGameSession",
- "UBlueprintCore",
- "FChatMessage",
- "FSocketBSD",
- "UField",
- "FText",
- "FName",
- "FAssetRegistry",
- "FModuleManager",
- "FAssetRegistryModule",
- "FAssetData",
- "UBlueprint",
- "UTexture2D",
- "FMemory",
- "ADroppedItem",
- "UBoolProperty",
- "APrimalDinoAIController",
- "APrimalStructureItemContainer",
- "UShooterGameInstance",
- "AMatineeActor",
- "UEngine",
- "UPrimalGlobals",
- "FSocket",
- "UPrimalGameData",
- "UPrimalEngramEntry",
- "UKismetSystemLibrary",
- "USphereComponent",
- "UPrimitiveComponent",
- "UActorComponent",
- "FHttpModule",
- "FHttpRequestWinInet",
- "FHttpResponseWinInet",
- "FOnlineSubsystemSteam",
- "APrimalStructureTurret",
- "FOverlapResult",
- "UVictoryCore"
- ],
- "functions":[
- "StaticLoadObject",
- "RaycastSingle",
- "StaticConstructObject"
- ],
- "globals":[
- "GEngine"
- ]
+ }
}
\ No newline at end of file
diff --git a/include/Poco/Poco/AbstractDelegate.h b/include/Poco/Poco/AbstractDelegate.h
new file mode 100644
index 00000000..9dea69a3
--- /dev/null
+++ b/include/Poco/Poco/AbstractDelegate.h
@@ -0,0 +1,110 @@
+//
+// AbstractDelegate.h
+//
+// Library: Foundation
+// Package: Events
+// Module: AbstractDelegate
+//
+// Implementation of the AbstractDelegate template.
+//
+// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_AbstractDelegate_INCLUDED
+#define Foundation_AbstractDelegate_INCLUDED
+
+
+#include "Poco/Foundation.h"
+
+
+namespace Poco {
+
+
+template
+class AbstractDelegate
+ /// Base class for Delegate and Expire.
+{
+public:
+ AbstractDelegate()
+ {
+ }
+
+ AbstractDelegate(const AbstractDelegate& /*del*/)
+ {
+ }
+
+ virtual ~AbstractDelegate()
+ {
+ }
+
+ virtual bool notify(const void* sender, TArgs& arguments) = 0;
+ /// Invokes the delegate's callback function.
+ /// Returns true if successful, or false if the delegate
+ /// has been disabled or has expired.
+
+ virtual bool equals(const AbstractDelegate& other) const = 0;
+ /// Compares the AbstractDelegate with the other one for equality.
+
+ virtual AbstractDelegate* clone() const = 0;
+ /// Returns a deep copy of the AbstractDelegate.
+
+ virtual void disable() = 0;
+ /// Disables the delegate, which is done prior to removal.
+
+ virtual const AbstractDelegate* unwrap() const
+ /// Returns the unwrapped delegate. Must be overridden by decorators
+ /// like Expire.
+ {
+ return this;
+ }
+};
+
+
+template <>
+class AbstractDelegate
+ /// Base class for Delegate and Expire.
+{
+public:
+ AbstractDelegate()
+ {
+ }
+
+ AbstractDelegate(const AbstractDelegate&)
+ {
+ }
+
+ virtual ~AbstractDelegate()
+ {
+ }
+
+ virtual bool notify(const void* sender) = 0;
+ /// Invokes the delegate's callback function.
+ /// Returns true if successful, or false if the delegate
+ /// has been disabled or has expired.
+
+ virtual bool equals(const AbstractDelegate& other) const = 0;
+ /// Compares the AbstractDelegate with the other one for equality.
+
+ virtual AbstractDelegate* clone() const = 0;
+ /// Returns a deep copy of the AbstractDelegate.
+
+ virtual void disable() = 0;
+ /// Disables the delegate, which is done prior to removal.
+
+ virtual const AbstractDelegate* unwrap() const
+ /// Returns the unwrapped delegate. Must be overridden by decorators
+ /// like Expire.
+ {
+ return this;
+ }
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_AbstractDelegate_INCLUDED
diff --git a/include/Poco/Poco/AbstractEvent.h b/include/Poco/Poco/AbstractEvent.h
new file mode 100644
index 00000000..d3724c90
--- /dev/null
+++ b/include/Poco/Poco/AbstractEvent.h
@@ -0,0 +1,561 @@
+//
+// AbstractEvent.h
+//
+// Library: Foundation
+// Package: Events
+// Module: AbstractEvent
+//
+// Definition of the AbstractEvent class.
+//
+// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_AbstractFoundation_INCLUDED
+#define Foundation_AbstractFoundation_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/SingletonHolder.h"
+#include "Poco/SharedPtr.h"
+#include "Poco/ActiveResult.h"
+#include "Poco/ActiveMethod.h"
+#include "Poco/Mutex.h"
+
+
+namespace Poco {
+
+
+template
+class AbstractEvent
+ /// An AbstractEvent is the base class of all events.
+ /// It works similar to the way C# handles notifications (aka events in C#).
+ ///
+ /// Events can be used to send information to a set of delegates
+ /// which are registered with the event. The type of the data is specified with
+ /// the template parameter TArgs. The TStrategy parameter must be a subclass
+ /// of NotificationStrategy. The parameter TDelegate can either be a subclass of AbstractDelegate
+ /// or of AbstractPriorityDelegate.
+ ///
+ /// Note that AbstractEvent should never be used directly. One ought to use
+ /// one of its subclasses which set the TStrategy and TDelegate template parameters
+ /// to fixed values. For most use-cases the BasicEvent template will be sufficient:
+ ///
+ /// #include "Poco/BasicEvent.h"
+ /// #include "Poco/Delegate.h"
+ ///
+ /// Note that as of release 1.4.2, the behavior of BasicEvent equals that of FIFOEvent,
+ /// so the FIFOEvent class is no longer necessary and provided for backwards compatibility
+ /// only.
+ ///
+ /// BasicEvent works with a standard delegate. They allow one object to register
+ /// one or more delegates with an event. In contrast, a PriorityDelegate comes with an attached priority value
+ /// and allows one object to register for one priority value one or more delegates. Note that PriorityDelegates
+ /// only work with PriorityEvents:
+ ///
+ /// #include "Poco/PriorityEvent.h"
+ /// #include "Poco/PriorityDelegate.h"
+ ///
+ /// Use events by adding them as public members to the object which is throwing notifications:
+ ///
+ /// class MyData
+ /// {
+ /// public:
+ /// Poco::BasicEvent dataChanged;
+ ///
+ /// MyData();
+ /// ...
+ /// void setData(int i);
+ /// ...
+ /// private:
+ /// int _data;
+ /// };
+ ///
+ /// Firing the event is done either by calling the event's notify() or notifyAsync() method:
+ ///
+ /// void MyData::setData(int i)
+ /// {
+ /// this->_data = i;
+ /// dataChanged.notify(this, this->_data);
+ /// }
+ ///
+ /// Alternatively, instead of notify(), operator () can be used.
+ ///
+ /// void MyData::setData(int i)
+ /// {
+ /// this->_data = i;
+ /// dataChanged(this, this->_data);
+ /// }
+ ///
+ /// Note that operator (), notify() and notifyAsync() do not catch exceptions, i.e. in case a
+ /// delegate throws an exception, notifying is immediately aborted and the exception is propagated
+ /// back to the caller.
+ ///
+ /// Delegates can register methods at the event. In the case of a BasicEvent
+ /// the Delegate template is used, in case of an PriorityEvent a PriorityDelegate is used.
+ /// Mixing of delegates, e.g. using a PriorityDelegate with a BasicEvent is not allowed and
+ /// can lead to compile-time and/or run-time errors. The standalone delegate() functions
+ /// can be used to construct Delegate objects.
+ ///
+ /// Events require the observers to have one of the following method signatures:
+ ///
+ /// void onEvent(const void* pSender, TArgs& args);
+ /// void onEvent(TArgs& args);
+ /// static void onEvent(const void* pSender, TArgs& args);
+ /// static void onEvent(void* pSender, TArgs& args);
+ /// static void onEvent(TArgs& args);
+ ///
+ /// For performance reasons arguments are always sent by reference. This also allows observers
+ /// to modify the event argument. To prevent that, use <[const TArg]> as template
+ /// parameter. A non-conformant method signature leads to compile errors.
+ ///
+ /// Assuming that the observer meets the method signature requirement, it can register
+ /// this method with the += operator:
+ ///
+ /// class MyController
+ /// {
+ /// protected:
+ /// MyData _data;
+ ///
+ /// void onDataChanged(void* pSender, int& data);
+ /// ...
+ /// };
+ ///
+ /// MyController::MyController()
+ /// {
+ /// _data.dataChanged += delegate(this, &MyController::onDataChanged);
+ /// }
+ ///
+ /// In some cases it might be desirable to work with automatically expiring registrations. Simply add
+ /// to delegate as 3rd parameter a expireValue (in milliseconds):
+ ///
+ /// _data.dataChanged += delegate(this, &MyController::onDataChanged, 1000);
+ ///
+ /// This will add a delegate to the event which will automatically be removed in 1000 millisecs.
+ ///
+ /// Unregistering happens via the -= operator. Forgetting to unregister a method will lead to
+ /// segmentation faults later, when one tries to send a notify to a no longer existing object.
+ ///
+ /// MyController::~MyController()
+ /// {
+ /// _data.dataChanged -= delegate(this, &MyController::onDataChanged);
+ /// }
+ ///
+ /// Working with PriorityDelegate's as similar to working with BasicEvent.
+ /// Instead of delegate(), the priorityDelegate() function must be used
+ /// to create the PriorityDelegate.
+{
+public:
+ typedef TDelegate* DelegateHandle;
+ typedef TArgs Args;
+
+ AbstractEvent():
+ _executeAsync(this, &AbstractEvent::executeAsyncImpl),
+ _enabled(true)
+ {
+ }
+
+ AbstractEvent(const TStrategy& strat):
+ _executeAsync(this, &AbstractEvent::executeAsyncImpl),
+ _strategy(strat),
+ _enabled(true)
+ {
+ }
+
+ virtual ~AbstractEvent()
+ {
+ }
+
+ void operator += (const TDelegate& aDelegate)
+ /// Adds a delegate to the event.
+ ///
+ /// Exact behavior is determined by the TStrategy.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _strategy.add(aDelegate);
+ }
+
+ void operator -= (const TDelegate& aDelegate)
+ /// Removes a delegate from the event.
+ ///
+ /// If the delegate is not found, this function does nothing.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _strategy.remove(aDelegate);
+ }
+
+ DelegateHandle add(const TDelegate& aDelegate)
+ /// Adds a delegate to the event.
+ ///
+ /// Exact behavior is determined by the TStrategy.
+ ///
+ /// Returns a DelegateHandle which can be used in call to
+ /// remove() to remove the delegate.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ return _strategy.add(aDelegate);
+ }
+
+ void remove(DelegateHandle delegateHandle)
+ /// Removes a delegate from the event using a DelegateHandle
+ /// returned by add().
+ ///
+ /// If the delegate is not found, this function does nothing.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _strategy.remove(delegateHandle);
+ }
+
+ void operator () (const void* pSender, TArgs& args)
+ /// Shortcut for notify(pSender, args);
+ {
+ notify(pSender, args);
+ }
+
+ void operator () (TArgs& args)
+ /// Shortcut for notify(args).
+ {
+ notify(0, args);
+ }
+
+ void notify(const void* pSender, TArgs& args)
+ /// Sends a notification to all registered delegates. The order is
+ /// determined by the TStrategy. This method is blocking. While executing,
+ /// the list of delegates may be modified. These changes don't
+ /// influence the current active notifications but are activated with
+ /// the next notify. If a delegate is removed during a notify(), the
+ /// delegate will no longer be invoked (unless it has already been
+ /// invoked prior to removal). If one of the delegates throws an exception,
+ /// the notify method is immediately aborted and the exception is propagated
+ /// to the caller.
+ {
+ Poco::ScopedLockWithUnlock lock(_mutex);
+
+ if (!_enabled) return;
+
+ // thread-safeness:
+ // copy should be faster and safer than blocking until
+ // execution ends
+ TStrategy strategy(_strategy);
+ lock.unlock();
+ strategy.notify(pSender, args);
+ }
+
+ bool hasDelegates() const
+ /// Returns true if there are registered delegates.
+ {
+ return !empty();
+ }
+
+ ActiveResult notifyAsync(const void* pSender, const TArgs& args)
+ /// Sends a notification to all registered delegates. The order is
+ /// determined by the TStrategy. This method is not blocking and will
+ /// immediately return. The delegates are invoked in a separate thread.
+ /// Call activeResult.wait() to wait until the notification has ended.
+ /// While executing, other objects can change the delegate list. These changes don't
+ /// influence the current active notifications but are activated with
+ /// the next notify. If a delegate is removed during a notify(), the
+ /// delegate will no longer be invoked (unless it has already been
+ /// invoked prior to removal). If one of the delegates throws an exception,
+ /// the execution is aborted and the exception is propagated to the caller.
+ {
+ NotifyAsyncParams params(pSender, args);
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+
+ // thread-safeness:
+ // copy should be faster and safer than blocking until
+ // execution ends
+ // make a copy of the strategy here to guarantee that
+ // between notifyAsync and the execution of the method no changes can occur
+
+ params.ptrStrat = SharedPtr(new TStrategy(_strategy));
+ params.enabled = _enabled;
+ }
+ ActiveResult result = _executeAsync(params);
+ return result;
+ }
+
+ void enable()
+ /// Enables the event.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _enabled = true;
+ }
+
+ void disable()
+ /// Disables the event. notify and notifyAsnyc will be ignored,
+ /// but adding/removing delegates is still allowed.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _enabled = false;
+ }
+
+ bool isEnabled() const
+ /// Returns true if event is enabled.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ return _enabled;
+ }
+
+ void clear()
+ /// Removes all delegates.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _strategy.clear();
+ }
+
+ bool empty() const
+ /// Checks if any delegates are registered at the delegate.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ return _strategy.empty();
+ }
+
+protected:
+ struct NotifyAsyncParams
+ {
+ SharedPtr ptrStrat;
+ const void* pSender;
+ TArgs args;
+ bool enabled;
+
+ NotifyAsyncParams(const void* pSend, const TArgs& a):ptrStrat(), pSender(pSend), args(a), enabled(true)
+ /// Default constructor reduces the need for TArgs to have an empty constructor, only copy constructor is needed.
+ {
+ }
+ };
+
+ ActiveMethod _executeAsync;
+
+ TArgs executeAsyncImpl(const NotifyAsyncParams& par)
+ {
+ if (!par.enabled)
+ {
+ return par.args;
+ }
+
+ NotifyAsyncParams params = par;
+ TArgs retArgs(params.args);
+ params.ptrStrat->notify(params.pSender, retArgs);
+ return retArgs;
+ }
+
+ TStrategy _strategy; /// The strategy used to notify observers.
+ bool _enabled; /// Stores if an event is enabled. Notifies on disabled events have no effect
+ /// but it is possible to change the observers.
+ mutable TMutex _mutex;
+
+private:
+ AbstractEvent(const AbstractEvent& other);
+ AbstractEvent& operator = (const AbstractEvent& other);
+};
+
+
+template
+class AbstractEvent
+{
+public:
+ typedef TDelegate* DelegateHandle;
+
+ AbstractEvent():
+ _executeAsync(this, &AbstractEvent::executeAsyncImpl),
+ _enabled(true)
+ {
+ }
+
+ AbstractEvent(const TStrategy& strat):
+ _executeAsync(this, &AbstractEvent::executeAsyncImpl),
+ _strategy(strat),
+ _enabled(true)
+ {
+ }
+
+ virtual ~AbstractEvent()
+ {
+ }
+
+ void operator += (const TDelegate& aDelegate)
+ /// Adds a delegate to the event.
+ ///
+ /// Exact behavior is determined by the TStrategy.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _strategy.add(aDelegate);
+ }
+
+ void operator -= (const TDelegate& aDelegate)
+ /// Removes a delegate from the event.
+ ///
+ /// If the delegate is not found, this function does nothing.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _strategy.remove(aDelegate);
+ }
+
+ DelegateHandle add(const TDelegate& aDelegate)
+ /// Adds a delegate to the event.
+ ///
+ /// Exact behavior is determined by the TStrategy.
+ ///
+ /// Returns a DelegateHandle which can be used in call to
+ /// remove() to remove the delegate.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ return _strategy.add(aDelegate);
+ }
+
+ void remove(DelegateHandle delegateHandle)
+ /// Removes a delegate from the event using a DelegateHandle
+ /// returned by add().
+ ///
+ /// If the delegate is not found, this function does nothing.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _strategy.remove(delegateHandle);
+ }
+
+ void operator () (const void* pSender)
+ /// Shortcut for notify(pSender, args);
+ {
+ notify(pSender);
+ }
+
+ void operator () ()
+ /// Shortcut for notify(args).
+ {
+ notify(0);
+ }
+
+ void notify(const void* pSender)
+ /// Sends a notification to all registered delegates. The order is
+ /// determined by the TStrategy. This method is blocking. While executing,
+ /// the list of delegates may be modified. These changes don't
+ /// influence the current active notifications but are activated with
+ /// the next notify. If a delegate is removed during a notify(), the
+ /// delegate will no longer be invoked (unless it has already been
+ /// invoked prior to removal). If one of the delegates throws an exception,
+ /// the notify method is immediately aborted and the exception is propagated
+ /// to the caller.
+ {
+ Poco::ScopedLockWithUnlock lock(_mutex);
+
+ if (!_enabled) return;
+
+ // thread-safeness:
+ // copy should be faster and safer than blocking until
+ // execution ends
+ TStrategy strategy(_strategy);
+ lock.unlock();
+ strategy.notify(pSender);
+ }
+
+ ActiveResult notifyAsync(const void* pSender)
+ /// Sends a notification to all registered delegates. The order is
+ /// determined by the TStrategy. This method is not blocking and will
+ /// immediately return. The delegates are invoked in a separate thread.
+ /// Call activeResult.wait() to wait until the notification has ended.
+ /// While executing, other objects can change the delegate list. These changes don't
+ /// influence the current active notifications but are activated with
+ /// the next notify. If a delegate is removed during a notify(), the
+ /// delegate will no longer be invoked (unless it has already been
+ /// invoked prior to removal). If one of the delegates throws an exception,
+ /// the execution is aborted and the exception is propagated to the caller.
+ {
+ NotifyAsyncParams params(pSender);
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+
+ // thread-safeness:
+ // copy should be faster and safer than blocking until
+ // execution ends
+ // make a copy of the strategy here to guarantee that
+ // between notifyAsync and the execution of the method no changes can occur
+
+ params.ptrStrat = SharedPtr(new TStrategy(_strategy));
+ params.enabled = _enabled;
+ }
+ ActiveResult result = _executeAsync(params);
+ return result;
+ }
+
+ void enable()
+ /// Enables the event.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _enabled = true;
+ }
+
+ void disable()
+ /// Disables the event. notify and notifyAsnyc will be ignored,
+ /// but adding/removing delegates is still allowed.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _enabled = false;
+ }
+
+ bool isEnabled() const
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ return _enabled;
+ }
+
+ void clear()
+ /// Removes all delegates.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ _strategy.clear();
+ }
+
+ bool empty() const
+ /// Checks if any delegates are registered at the delegate.
+ {
+ typename TMutex::ScopedLock lock(_mutex);
+ return _strategy.empty();
+ }
+
+protected:
+ struct NotifyAsyncParams
+ {
+ SharedPtr ptrStrat;
+ const void* pSender;
+ bool enabled;
+
+ NotifyAsyncParams(const void* pSend):ptrStrat(), pSender(pSend), enabled(true)
+ /// Default constructor reduces the need for TArgs to have an empty constructor, only copy constructor is needed.
+ {
+ }
+ };
+
+ ActiveMethod _executeAsync;
+
+ void executeAsyncImpl(const NotifyAsyncParams& par)
+ {
+ if (!par.enabled)
+ {
+ return;
+ }
+
+ NotifyAsyncParams params = par;
+ params.ptrStrat->notify(params.pSender);
+ return;
+ }
+
+ TStrategy _strategy; /// The strategy used to notify observers.
+ bool _enabled; /// Stores if an event is enabled. Notifies on disabled events have no effect
+ /// but it is possible to change the observers.
+ mutable TMutex _mutex;
+
+private:
+ AbstractEvent(const AbstractEvent& other);
+ AbstractEvent& operator = (const AbstractEvent& other);
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_AbstractFoundation_INCLUDED
diff --git a/include/Poco/Poco/ActiveMethod.h b/include/Poco/Poco/ActiveMethod.h
new file mode 100644
index 00000000..8ab48357
--- /dev/null
+++ b/include/Poco/Poco/ActiveMethod.h
@@ -0,0 +1,218 @@
+//
+// ActiveMethod.h
+//
+// Library: Foundation
+// Package: Threading
+// Module: ActiveObjects
+//
+// Definition of the ActiveMethod class.
+//
+// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_ActiveMethod_INCLUDED
+#define Foundation_ActiveMethod_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/ActiveResult.h"
+#include "Poco/ActiveRunnable.h"
+#include "Poco/ActiveStarter.h"
+#include "Poco/AutoPtr.h"
+
+
+namespace Poco {
+
+
+template >
+class ActiveMethod
+ /// An active method is a method that, when called, executes
+ /// in its own thread. ActiveMethod's take exactly one
+ /// argument and can return a value. To pass more than one
+ /// argument to the method, use a struct.
+ /// The following example shows how to add an ActiveMethod
+ /// to a class:
+ ///
+ /// class ActiveObject
+ /// {
+ /// public:
+ /// ActiveObject():
+ /// exampleActiveMethod(this, &ActiveObject::exampleActiveMethodImpl)
+ /// {
+ /// }
+ ///
+ /// ActiveMethod exampleActiveMethod;
+ ///
+ /// protected:
+ /// std::string exampleActiveMethodImpl(const std::string& arg)
+ /// {
+ /// ...
+ /// }
+ /// };
+ ///
+ /// And following is an example that shows how to invoke an ActiveMethod.
+ ///
+ /// ActiveObject myActiveObject;
+ /// ActiveResult result = myActiveObject.exampleActiveMethod("foo");
+ /// ...
+ /// result.wait();
+ /// std::cout << result.data() << std::endl;
+ ///
+ /// The way an ActiveMethod is started can be changed by passing a StarterType
+ /// template argument with a corresponding class. The default ActiveStarter
+ /// starts the method in its own thread, obtained from a thread pool.
+ ///
+ /// For an alternative implementation of StarterType, see ActiveDispatcher.
+ ///
+ /// For methods that do not require an argument or a return value, the Void
+ /// class can be used.
+{
+public:
+ typedef ResultType (OwnerType::*Callback)(const ArgType&);
+ typedef ActiveResult ActiveResultType;
+ typedef ActiveRunnable ActiveRunnableType;
+
+ ActiveMethod(OwnerType* pOwner, Callback method):
+ _pOwner(pOwner),
+ _method(method)
+ /// Creates an ActiveMethod object.
+ {
+ poco_check_ptr (pOwner);
+ }
+
+ ActiveResultType operator () (const ArgType& arg)
+ /// Invokes the ActiveMethod.
+ {
+ ActiveResultType result(new ActiveResultHolder());
+ ActiveRunnableBase::Ptr pRunnable(new ActiveRunnableType(_pOwner, _method, arg, result));
+ StarterType::start(_pOwner, pRunnable);
+ return result;
+ }
+
+ ActiveMethod(const ActiveMethod& other):
+ _pOwner(other._pOwner),
+ _method(other._method)
+ {
+ }
+
+ ActiveMethod& operator = (const ActiveMethod& other)
+ {
+ ActiveMethod tmp(other);
+ swap(tmp);
+ return *this;
+ }
+
+ void swap(ActiveMethod& other)
+ {
+ std::swap(_pOwner, other._pOwner);
+ std::swap(_method, other._method);
+ }
+
+private:
+ ActiveMethod();
+
+ OwnerType* _pOwner;
+ Callback _method;
+};
+
+
+
+template
+class ActiveMethod
+ /// An active method is a method that, when called, executes
+ /// in its own thread. ActiveMethod's take exactly one
+ /// argument and can return a value. To pass more than one
+ /// argument to the method, use a struct.
+ /// The following example shows how to add an ActiveMethod
+ /// to a class:
+ ///
+ /// class ActiveObject
+ /// {
+ /// public:
+ /// ActiveObject():
+ /// exampleActiveMethod(this, &ActiveObject::exampleActiveMethodImpl)
+ /// {
+ /// }
+ ///
+ /// ActiveMethod exampleActiveMethod;
+ ///
+ /// protected:
+ /// std::string exampleActiveMethodImpl(const std::string& arg)
+ /// {
+ /// ...
+ /// }
+ /// };
+ ///
+ /// And following is an example that shows how to invoke an ActiveMethod.
+ ///
+ /// ActiveObject myActiveObject;
+ /// ActiveResult result = myActiveObject.exampleActiveMethod("foo");
+ /// ...
+ /// result.wait();
+ /// std::cout << result.data() << std::endl;
+ ///
+ /// The way an ActiveMethod is started can be changed by passing a StarterType
+ /// template argument with a corresponding class. The default ActiveStarter
+ /// starts the method in its own thread, obtained from a thread pool.
+ ///
+ /// For an alternative implementation of StarterType, see ActiveDispatcher.
+ ///
+ /// For methods that do not require an argument or a return value, simply use void.
+{
+public:
+ typedef ResultType (OwnerType::*Callback)(void);
+ typedef ActiveResult ActiveResultType;
+ typedef ActiveRunnable ActiveRunnableType;
+
+ ActiveMethod(OwnerType* pOwner, Callback method):
+ _pOwner(pOwner),
+ _method(method)
+ /// Creates an ActiveMethod object.
+ {
+ poco_check_ptr (pOwner);
+ }
+
+ ActiveResultType operator () (void)
+ /// Invokes the ActiveMethod.
+ {
+ ActiveResultType result(new ActiveResultHolder());
+ ActiveRunnableBase::Ptr pRunnable(new ActiveRunnableType(_pOwner, _method, result));
+ StarterType::start(_pOwner, pRunnable);
+ return result;
+ }
+
+ ActiveMethod(const ActiveMethod& other):
+ _pOwner(other._pOwner),
+ _method(other._method)
+ {
+ }
+
+ ActiveMethod& operator = (const ActiveMethod& other)
+ {
+ ActiveMethod tmp(other);
+ swap(tmp);
+ return *this;
+ }
+
+ void swap(ActiveMethod& other)
+ {
+ std::swap(_pOwner, other._pOwner);
+ std::swap(_method, other._method);
+ }
+
+private:
+ ActiveMethod();
+
+ OwnerType* _pOwner;
+ Callback _method;
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_ActiveMethod_INCLUDED
diff --git a/include/Poco/Poco/ActiveResult.h b/include/Poco/Poco/ActiveResult.h
new file mode 100644
index 00000000..04bd1530
--- /dev/null
+++ b/include/Poco/Poco/ActiveResult.h
@@ -0,0 +1,495 @@
+//
+// ActiveResult.h
+//
+// Library: Foundation
+// Package: Threading
+// Module: ActiveObjects
+//
+// Definition of the ActiveResult class.
+//
+// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_ActiveResult_INCLUDED
+#define Foundation_ActiveResult_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Mutex.h"
+#include "Poco/Event.h"
+#include "Poco/RefCountedObject.h"
+#include "Poco/Exception.h"
+#include
+
+
+namespace Poco {
+
+
+template
+class ActiveResultHolder: public RefCountedObject
+ /// This class holds the result of an asynchronous method
+ /// invocation. It is used to pass the result from the
+ /// execution thread back to the invocation thread.
+ /// The class uses reference counting for memory management.
+ /// Do not use this class directly, use ActiveResult instead.
+{
+public:
+ ActiveResultHolder():
+ _pData(0),
+ _pExc(0),
+ _event(Event::EVENT_MANUALRESET)
+ /// Creates an ActiveResultHolder.
+ {
+ }
+
+ ResultType& data()
+ /// Returns a reference to the actual result.
+ {
+ poco_check_ptr(_pData);
+ return *_pData;
+ }
+
+ void data(ResultType* pData)
+ {
+ delete _pData;
+ _pData = pData;
+ }
+
+ void wait()
+ /// Pauses the caller until the result becomes available.
+ {
+ _event.wait();
+ }
+
+ bool tryWait(long milliseconds)
+ /// Waits up to the specified interval for the result to
+ /// become available. Returns true if the result became
+ /// available, false otherwise.
+ {
+ return _event.tryWait(milliseconds);
+ }
+
+ void wait(long milliseconds)
+ /// Waits up to the specified interval for the result to
+ /// become available. Throws a TimeoutException if the
+ /// result did not became available.
+ {
+ _event.wait(milliseconds);
+ }
+
+ void notify()
+ /// Notifies the invoking thread that the result became available.
+ {
+ _event.set();
+ }
+
+ bool failed() const
+ /// Returns true if the active method failed (and threw an exception).
+ /// Information about the exception can be obtained by calling error().
+ {
+ return _pExc != 0;
+ }
+
+ std::string error() const
+ /// If the active method threw an exception, a textual representation
+ /// of the exception is returned. An empty string is returned if the
+ /// active method completed successfully.
+ {
+ if (_pExc)
+ return _pExc->message();
+ else
+ return std::string();
+ }
+
+ Exception* exception() const
+ /// If the active method threw an exception, a clone of the exception
+ /// object is returned, otherwise null.
+ {
+ return _pExc;
+ }
+
+ void error(const Exception& exc)
+ /// Sets the exception.
+ {
+ delete _pExc;
+ _pExc = exc.clone();
+ }
+
+ void error(const std::string& msg)
+ /// Sets the exception.
+ {
+ delete _pExc;
+ _pExc = new UnhandledException(msg);
+ }
+
+protected:
+ ~ActiveResultHolder()
+ {
+ delete _pData;
+ delete _pExc;
+ }
+
+private:
+ ResultType* _pData;
+ Exception* _pExc;
+ Event _event;
+};
+
+
+
+template <>
+class ActiveResultHolder: public RefCountedObject
+{
+public:
+ ActiveResultHolder():
+ _pExc(0),
+ _event(Event::EVENT_MANUALRESET)
+ /// Creates an ActiveResultHolder.
+ {
+ }
+
+ void wait()
+ /// Pauses the caller until the result becomes available.
+ {
+ _event.wait();
+ }
+
+ bool tryWait(long milliseconds)
+ /// Waits up to the specified interval for the result to
+ /// become available. Returns true if the result became
+ /// available, false otherwise.
+ {
+ return _event.tryWait(milliseconds);
+ }
+
+ void wait(long milliseconds)
+ /// Waits up to the specified interval for the result to
+ /// become available. Throws a TimeoutException if the
+ /// result did not became available.
+ {
+ _event.wait(milliseconds);
+ }
+
+ void notify()
+ /// Notifies the invoking thread that the result became available.
+ {
+ _event.set();
+ }
+
+ bool failed() const
+ /// Returns true if the active method failed (and threw an exception).
+ /// Information about the exception can be obtained by calling error().
+ {
+ return _pExc != 0;
+ }
+
+ std::string error() const
+ /// If the active method threw an exception, a textual representation
+ /// of the exception is returned. An empty string is returned if the
+ /// active method completed successfully.
+ {
+ if (_pExc)
+ return _pExc->message();
+ else
+ return std::string();
+ }
+
+ Exception* exception() const
+ /// If the active method threw an exception, a clone of the exception
+ /// object is returned, otherwise null.
+ {
+ return _pExc;
+ }
+
+ void error(const Exception& exc)
+ /// Sets the exception.
+ {
+ delete _pExc;
+ _pExc = exc.clone();
+ }
+
+ void error(const std::string& msg)
+ /// Sets the exception.
+ {
+ delete _pExc;
+ _pExc = new UnhandledException(msg);
+ }
+
+protected:
+ ~ActiveResultHolder()
+ {
+ delete _pExc;
+ }
+
+private:
+ Exception* _pExc;
+ Event _event;
+};
+
+
+template
+class ActiveResult
+ /// This class holds the result of an asynchronous method
+ /// invocation (see class ActiveMethod). It is used to pass the
+ /// result from the execution thread back to the invocation thread.
+{
+public:
+ typedef RT ResultType;
+ typedef ActiveResultHolder ActiveResultHolderType;
+
+ ActiveResult(ActiveResultHolderType* pHolder):
+ _pHolder(pHolder)
+ /// Creates the active result. For internal use only.
+ {
+ poco_check_ptr (pHolder);
+ }
+
+ ActiveResult(const ActiveResult& result)
+ /// Copy constructor.
+ {
+ _pHolder = result._pHolder;
+ _pHolder->duplicate();
+ }
+
+ ~ActiveResult()
+ /// Destroys the result.
+ {
+ _pHolder->release();
+ }
+
+ ActiveResult& operator = (const ActiveResult& result)
+ /// Assignment operator.
+ {
+ ActiveResult tmp(result);
+ swap(tmp);
+ return *this;
+ }
+
+ void swap(ActiveResult& result)
+ {
+ using std::swap;
+ swap(_pHolder, result._pHolder);
+ }
+
+ ResultType& data() const
+ /// Returns a reference to the result data.
+ {
+ return _pHolder->data();
+ }
+
+ void data(ResultType* pValue)
+ {
+ _pHolder->data(pValue);
+ }
+
+ void wait()
+ /// Pauses the caller until the result becomes available.
+ {
+ _pHolder->wait();
+ }
+
+ bool tryWait(long milliseconds)
+ /// Waits up to the specified interval for the result to
+ /// become available. Returns true if the result became
+ /// available, false otherwise.
+ {
+ return _pHolder->tryWait(milliseconds);
+ }
+
+ void wait(long milliseconds)
+ /// Waits up to the specified interval for the result to
+ /// become available. Throws a TimeoutException if the
+ /// result did not became available.
+ {
+ _pHolder->wait(milliseconds);
+ }
+
+ bool available() const
+ /// Returns true if a result is available.
+ {
+ return _pHolder->tryWait(0);
+ }
+
+ bool failed() const
+ /// Returns true if the active method failed (and threw an exception).
+ /// Information about the exception can be obtained by calling error().
+ {
+ return _pHolder->failed();
+ }
+
+ std::string error() const
+ /// If the active method threw an exception, a textual representation
+ /// of the exception is returned. An empty string is returned if the
+ /// active method completed successfully.
+ {
+ return _pHolder->error();
+ }
+
+ Exception* exception() const
+ /// If the active method threw an exception, a clone of the exception
+ /// object is returned, otherwise null.
+ {
+ return _pHolder->exception();
+ }
+
+ void notify()
+ /// Notifies the invoking thread that the result became available.
+ /// For internal use only.
+ {
+ _pHolder->notify();
+ }
+
+ ResultType& data()
+ /// Returns a non-const reference to the result data. For internal
+ /// use only.
+ {
+ return _pHolder->data();
+ }
+
+ void error(const std::string& msg)
+ /// Sets the failed flag and the exception message.
+ {
+ _pHolder->error(msg);
+ }
+
+ void error(const Exception& exc)
+ /// Sets the failed flag and the exception message.
+ {
+ _pHolder->error(exc);
+ }
+
+private:
+ ActiveResult();
+
+ ActiveResultHolderType* _pHolder;
+};
+
+
+
+template <>
+class ActiveResult
+ /// This class holds the result of an asynchronous method
+ /// invocation (see class ActiveMethod). It is used to pass the
+ /// result from the execution thread back to the invocation thread.
+{
+public:
+ typedef ActiveResultHolder ActiveResultHolderType;
+
+ ActiveResult(ActiveResultHolderType* pHolder):
+ _pHolder(pHolder)
+ /// Creates the active result. For internal use only.
+ {
+ poco_check_ptr (pHolder);
+ }
+
+ ActiveResult(const ActiveResult& result)
+ /// Copy constructor.
+ {
+ _pHolder = result._pHolder;
+ _pHolder->duplicate();
+ }
+
+ ~ActiveResult()
+ /// Destroys the result.
+ {
+ _pHolder->release();
+ }
+
+ ActiveResult& operator = (const ActiveResult& result)
+ /// Assignment operator.
+ {
+ ActiveResult tmp(result);
+ swap(tmp);
+ return *this;
+ }
+
+ void swap(ActiveResult& result)
+ {
+ using std::swap;
+ swap(_pHolder, result._pHolder);
+ }
+
+ void wait()
+ /// Pauses the caller until the result becomes available.
+ {
+ _pHolder->wait();
+ }
+
+ bool tryWait(long milliseconds)
+ /// Waits up to the specified interval for the result to
+ /// become available. Returns true if the result became
+ /// available, false otherwise.
+ {
+ return _pHolder->tryWait(milliseconds);
+ }
+
+ void wait(long milliseconds)
+ /// Waits up to the specified interval for the result to
+ /// become available. Throws a TimeoutException if the
+ /// result did not became available.
+ {
+ _pHolder->wait(milliseconds);
+ }
+
+ bool available() const
+ /// Returns true if a result is available.
+ {
+ return _pHolder->tryWait(0);
+ }
+
+ bool failed() const
+ /// Returns true if the active method failed (and threw an exception).
+ /// Information about the exception can be obtained by calling error().
+ {
+ return _pHolder->failed();
+ }
+
+ std::string error() const
+ /// If the active method threw an exception, a textual representation
+ /// of the exception is returned. An empty string is returned if the
+ /// active method completed successfully.
+ {
+ return _pHolder->error();
+ }
+
+ Exception* exception() const
+ /// If the active method threw an exception, a clone of the exception
+ /// object is returned, otherwise null.
+ {
+ return _pHolder->exception();
+ }
+
+ void notify()
+ /// Notifies the invoking thread that the result became available.
+ /// For internal use only.
+ {
+ _pHolder->notify();
+ }
+
+ void error(const std::string& msg)
+ /// Sets the failed flag and the exception message.
+ {
+ _pHolder->error(msg);
+ }
+
+ void error(const Exception& exc)
+ /// Sets the failed flag and the exception message.
+ {
+ _pHolder->error(exc);
+ }
+
+private:
+ ActiveResult();
+
+ ActiveResultHolderType* _pHolder;
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_ActiveResult_INCLUDED
diff --git a/include/Poco/Poco/ActiveRunnable.h b/include/Poco/Poco/ActiveRunnable.h
new file mode 100644
index 00000000..051f3478
--- /dev/null
+++ b/include/Poco/Poco/ActiveRunnable.h
@@ -0,0 +1,231 @@
+//
+// ActiveRunnable.h
+//
+// Library: Foundation
+// Package: Threading
+// Module: ActiveObjects
+//
+// Definition of the ActiveRunnable class.
+//
+// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_ActiveRunnable_INCLUDED
+#define Foundation_ActiveRunnable_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/ActiveResult.h"
+#include "Poco/Runnable.h"
+#include "Poco/RefCountedObject.h"
+#include "Poco/AutoPtr.h"
+#include "Poco/Exception.h"
+
+
+namespace Poco {
+
+
+class ActiveRunnableBase: public Runnable, public RefCountedObject
+ /// The base class for all ActiveRunnable instantiations.
+{
+public:
+ using Ptr = AutoPtr;
+};
+
+
+template
+class ActiveRunnable: public ActiveRunnableBase
+ /// This class is used by ActiveMethod.
+ /// See the ActiveMethod class for more information.
+{
+public:
+ typedef ResultType (OwnerType::*Callback)(const ArgType&);
+ typedef ActiveResult ActiveResultType;
+
+ ActiveRunnable(OwnerType* pOwner, Callback method, const ArgType& arg, const ActiveResultType& result):
+ _pOwner(pOwner),
+ _method(method),
+ _arg(arg),
+ _result(result)
+ {
+ poco_check_ptr (pOwner);
+ }
+
+ void run()
+ {
+ ActiveRunnableBase::Ptr guard(this, false); // ensure automatic release when done
+ try
+ {
+ _result.data(new ResultType((_pOwner->*_method)(_arg)));
+ }
+ catch (Exception& e)
+ {
+ _result.error(e);
+ }
+ catch (std::exception& e)
+ {
+ _result.error(e.what());
+ }
+ catch (...)
+ {
+ _result.error("unknown exception");
+ }
+ _result.notify();
+ }
+
+private:
+ OwnerType* _pOwner;
+ Callback _method;
+ ArgType _arg;
+ ActiveResultType _result;
+};
+
+
+template
+class ActiveRunnable: public ActiveRunnableBase
+ /// This class is used by ActiveMethod.
+ /// See the ActiveMethod class for more information.
+{
+public:
+ typedef void (OwnerType::*Callback)(const ArgType&);
+ typedef ActiveResult ActiveResultType;
+
+ ActiveRunnable(OwnerType* pOwner, Callback method, const ArgType& arg, const ActiveResultType& result):
+ _pOwner(pOwner),
+ _method(method),
+ _arg(arg),
+ _result(result)
+ {
+ poco_check_ptr (pOwner);
+ }
+
+ void run()
+ {
+ ActiveRunnableBase::Ptr guard(this, false); // ensure automatic release when done
+ try
+ {
+ (_pOwner->*_method)(_arg);
+ }
+ catch (Exception& e)
+ {
+ _result.error(e);
+ }
+ catch (std::exception& e)
+ {
+ _result.error(e.what());
+ }
+ catch (...)
+ {
+ _result.error("unknown exception");
+ }
+ _result.notify();
+ }
+
+private:
+ OwnerType* _pOwner;
+ Callback _method;
+ ArgType _arg;
+ ActiveResultType _result;
+};
+
+
+template
+class ActiveRunnable: public ActiveRunnableBase
+ /// This class is used by ActiveMethod.
+ /// See the ActiveMethod class for more information.
+{
+public:
+ typedef ResultType (OwnerType::*Callback)();
+ typedef ActiveResult ActiveResultType;
+
+ ActiveRunnable(OwnerType* pOwner, Callback method, const ActiveResultType& result):
+ _pOwner(pOwner),
+ _method(method),
+ _result(result)
+ {
+ poco_check_ptr (pOwner);
+ }
+
+ void run()
+ {
+ ActiveRunnableBase::Ptr guard(this, false); // ensure automatic release when done
+ try
+ {
+ _result.data(new ResultType((_pOwner->*_method)()));
+ }
+ catch (Exception& e)
+ {
+ _result.error(e);
+ }
+ catch (std::exception& e)
+ {
+ _result.error(e.what());
+ }
+ catch (...)
+ {
+ _result.error("unknown exception");
+ }
+ _result.notify();
+ }
+
+private:
+ OwnerType* _pOwner;
+ Callback _method;
+ ActiveResultType _result;
+};
+
+
+template
+class ActiveRunnable: public ActiveRunnableBase
+ /// This class is used by ActiveMethod.
+ /// See the ActiveMethod class for more information.
+{
+public:
+ typedef void (OwnerType::*Callback)();
+ typedef ActiveResult ActiveResultType;
+
+ ActiveRunnable(OwnerType* pOwner, Callback method, const ActiveResultType& result):
+ _pOwner(pOwner),
+ _method(method),
+ _result(result)
+ {
+ poco_check_ptr (pOwner);
+ }
+
+ void run()
+ {
+ ActiveRunnableBase::Ptr guard(this, false); // ensure automatic release when done
+ try
+ {
+ (_pOwner->*_method)();
+ }
+ catch (Exception& e)
+ {
+ _result.error(e);
+ }
+ catch (std::exception& e)
+ {
+ _result.error(e.what());
+ }
+ catch (...)
+ {
+ _result.error("unknown exception");
+ }
+ _result.notify();
+ }
+
+private:
+ OwnerType* _pOwner;
+ Callback _method;
+ ActiveResultType _result;
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_ActiveRunnable_INCLUDED
diff --git a/include/Poco/Poco/ActiveStarter.h b/include/Poco/Poco/ActiveStarter.h
new file mode 100644
index 00000000..b79a31e8
--- /dev/null
+++ b/include/Poco/Poco/ActiveStarter.h
@@ -0,0 +1,48 @@
+//
+// ActiveStarter.h
+//
+// Library: Foundation
+// Package: Threading
+// Module: ActiveObjects
+//
+// Definition of the ActiveStarter class.
+//
+// Copyright (c) 2006-2007, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_ActiveStarter_INCLUDED
+#define Foundation_ActiveStarter_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/ThreadPool.h"
+#include "Poco/ActiveRunnable.h"
+
+
+namespace Poco {
+
+
+template
+class ActiveStarter
+ /// The default implementation of the StarterType
+ /// policy for ActiveMethod. It starts the method
+ /// in its own thread, obtained from the default
+ /// thread pool.
+{
+public:
+ static void start(OwnerType* /*pOwner*/, ActiveRunnableBase::Ptr pRunnable)
+ {
+ ThreadPool::defaultPool().start(*pRunnable);
+ pRunnable->duplicate(); // The runnable will release itself.
+ }
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_ActiveStarter_INCLUDED
diff --git a/include/Poco/Poco/Alignment.h b/include/Poco/Poco/Alignment.h
new file mode 100644
index 00000000..bf88db04
--- /dev/null
+++ b/include/Poco/Poco/Alignment.h
@@ -0,0 +1,25 @@
+//
+// Alignment.h
+//
+// Library: Foundation
+// Package: Dynamic
+// Module: Alignment
+//
+// Definition of the Alignment class.
+//
+// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Alignment_INCLUDED
+#define Foundation_Alignment_INCLUDED
+
+
+#include
+#define POCO_HAVE_ALIGNMENT
+
+
+#endif // Foundation_Alignment_INCLUDED
diff --git a/include/Poco/Poco/Any.h b/include/Poco/Poco/Any.h
new file mode 100644
index 00000000..ba6b7143
--- /dev/null
+++ b/include/Poco/Poco/Any.h
@@ -0,0 +1,633 @@
+//
+// Any.h
+//
+// Library: Foundation
+// Package: Core
+// Module: Any
+//
+// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
+// Extracted from Boost 1.33.1 lib and adapted for poco: Peter Schojer/AppliedInformatics 2006-02-02
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Any_INCLUDED
+#define Foundation_Any_INCLUDED
+
+
+#include "Poco/Exception.h"
+#include "Poco/MetaProgramming.h"
+#include
+#include
+#include
+
+
+namespace Poco {
+
+
+class Any;
+
+
+namespace Dynamic {
+
+class Var;
+class VarHolder;
+template class VarHolderImpl;
+
+}
+
+
+#ifndef POCO_NO_SOO
+
+
+template
+union Placeholder
+ /// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
+ /// object optimization, when enabled).
+ ///
+ /// If Holder fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
+ /// it will be placement-new-allocated into the local buffer
+ /// (i.e. there will be no heap-allocation). The local buffer size is one byte
+ /// larger - [POCO_SMALL_OBJECT_SIZE + 1], additional byte value indicating
+ /// where the object was allocated (0 => heap, 1 => local).
+{
+public:
+ struct Size
+ {
+ static const unsigned int value = SizeV;
+ };
+
+ Placeholder()
+ {
+ erase();
+ }
+
+ void erase()
+ {
+ std::memset(holder, 0, sizeof(Placeholder));
+ }
+
+ bool isLocal() const
+ {
+ return holder[SizeV] != 0;
+ }
+
+ void setLocal(bool local) const
+ {
+ holder[SizeV] = local ? 1 : 0;
+ }
+
+ PlaceholderT* content() const
+ {
+ if (isLocal())
+ return reinterpret_cast(holder);
+ else
+ return pHolder;
+ }
+
+// MSVC71,80 won't extend friendship to nested class (Any::Holder)
+#if !defined(POCO_MSVC_VERSION) || (defined(POCO_MSVC_VERSION) && (POCO_MSVC_VERSION > 80))
+private:
+#endif
+ typedef typename std::aligned_storage::type AlignerType;
+
+ PlaceholderT* pHolder;
+ mutable char holder[SizeV + 1];
+ AlignerType aligner;
+
+ friend class Any;
+ friend class Dynamic::Var;
+ friend class Dynamic::VarHolder;
+ template friend class Dynamic::VarHolderImpl;
+};
+
+
+#else // !POCO_NO_SOO
+
+
+template
+union Placeholder
+ /// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
+ /// object optimization, when enabled).
+ ///
+ /// If Holder fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
+ /// it will be placement-new-allocated into the local buffer
+ /// (i.e. there will be no heap-allocation). The local buffer size is one byte
+ /// larger - [POCO_SMALL_OBJECT_SIZE + 1], additional byte value indicating
+ /// where the object was allocated (0 => heap, 1 => local).
+{
+public:
+ Placeholder ()
+ {
+ }
+
+ PlaceholderT* content() const
+ {
+ return pHolder;
+ }
+
+// MSVC71,80 won't extend friendship to nested class (Any::Holder)
+#if !defined(POCO_MSVC_VERSION) || (defined(POCO_MSVC_VERSION) && (POCO_MSVC_VERSION > 80))
+private:
+#endif
+
+ PlaceholderT* pHolder;
+
+ friend class Any;
+ friend class Dynamic::Var;
+ friend class Dynamic::VarHolder;
+ template friend class Dynamic::VarHolderImpl;
+};
+
+
+#endif // POCO_NO_SOO
+
+
+class Any
+ /// An Any class represents a general type and is capable of storing any type, supporting type-safe extraction
+ /// of the internally stored data.
+ ///
+ /// Code taken from the Boost 1.33.1 library. Original copyright by Kevlin Henney. Modified for Poco
+ /// by Applied Informatics.
+ ///
+ /// Modified for small object optimization support (optionally supported through conditional compilation)
+ /// by Alex Fabijanic.
+{
+public:
+
+#ifndef POCO_NO_SOO
+
+ Any()
+ /// Creates an empty any type.
+ {
+ }
+
+ template
+ Any(const ValueType & value)
+ /// Creates an any which stores the init parameter inside.
+ ///
+ /// Example:
+ /// Any a(13);
+ /// Any a(string("12345"));
+ {
+ construct(value);
+ }
+
+ Any(const Any& other)
+ /// Copy constructor, works with both empty and initialized Any values.
+ {
+ if ((this != &other) && !other.empty())
+ construct(other);
+ }
+
+ ~Any()
+ /// Destructor. If Any is locally held, calls ValueHolder destructor;
+ /// otherwise, deletes the placeholder from the heap.
+ {
+ if (!empty())
+ {
+ if (_valueHolder.isLocal())
+ destruct();
+ else
+ delete content();
+ }
+ }
+
+ Any& swap(Any& other)
+ /// Swaps the content of the two Anys.
+ ///
+ /// When small object optimization is enabled, swap only
+ /// has no-throw guarantee when both (*this and other)
+ /// objects are allocated on the heap.
+ {
+ if (this == &other) return *this;
+
+ if (!_valueHolder.isLocal() && !other._valueHolder.isLocal())
+ {
+ std::swap(_valueHolder.pHolder, other._valueHolder.pHolder);
+ }
+ else
+ {
+ Any tmp(*this);
+ try
+ {
+ if (_valueHolder.isLocal()) destruct();
+ construct(other);
+ other = tmp;
+ }
+ catch (...)
+ {
+ construct(tmp);
+ throw;
+ }
+ }
+
+ return *this;
+ }
+
+ template
+ Any& operator = (const ValueType& rhs)
+ /// Assignment operator for all types != Any.
+ ///
+ /// Example:
+ /// Any a = 13;
+ /// Any a = string("12345");
+ {
+ construct(rhs);
+ return *this;
+ }
+
+ Any& operator = (const Any& rhs)
+ /// Assignment operator for Any.
+ {
+ if ((this != &rhs) && !rhs.empty())
+ construct(rhs);
+ else if ((this != &rhs) && rhs.empty())
+ _valueHolder.erase();
+
+ return *this;
+ }
+
+ bool empty() const
+ /// Returns true if the Any is empty.
+ {
+ char buf[POCO_SMALL_OBJECT_SIZE] = { 0 };
+ return 0 == std::memcmp(_valueHolder.holder, buf, POCO_SMALL_OBJECT_SIZE);
+ }
+
+ const std::type_info & type() const
+ /// Returns the type information of the stored content.
+ /// If the Any is empty typeid(void) is returned.
+ /// It is recommended to always query an Any for its type info before
+ /// trying to extract data via an AnyCast/RefAnyCast.
+ {
+ return empty() ? typeid(void) : content()->type();
+ }
+
+private:
+ class ValueHolder
+ {
+ public:
+ virtual ~ValueHolder() = default;
+
+ virtual const std::type_info & type() const = 0;
+ virtual void clone(Placeholder*) const = 0;
+ };
+
+ template
+ class Holder : public ValueHolder
+ {
+ public:
+ Holder(const ValueType & value) : _held(value)
+ {
+ }
+
+ virtual const std::type_info & type() const
+ {
+ return typeid(ValueType);
+ }
+
+ virtual void clone(Placeholder* pPlaceholder) const
+ {
+ if ((sizeof(Holder) <= POCO_SMALL_OBJECT_SIZE))
+ {
+ new ((ValueHolder*) pPlaceholder->holder) Holder(_held);
+ pPlaceholder->setLocal(true);
+ }
+ else
+ {
+ pPlaceholder->pHolder = new Holder(_held);
+ pPlaceholder->setLocal(false);
+ }
+ }
+
+ ValueType _held;
+
+ private:
+ Holder & operator = (const Holder &);
+ };
+
+ ValueHolder* content() const
+ {
+ return _valueHolder.content();
+ }
+
+ template
+ void construct(const ValueType& value)
+ {
+ if (sizeof(Holder) <= Placeholder::Size::value)
+ {
+ new (reinterpret_cast(_valueHolder.holder)) Holder(value);
+ _valueHolder.setLocal(true);
+ }
+ else
+ {
+ _valueHolder.pHolder = new Holder(value);
+ _valueHolder.setLocal(false);
+ }
+ }
+
+ void construct(const Any& other)
+ {
+ if (!other.empty())
+ other.content()->clone(&_valueHolder);
+ else
+ _valueHolder.erase();
+ }
+
+ void destruct()
+ {
+ content()->~ValueHolder();
+ }
+
+ Placeholder _valueHolder;
+
+
+#else // if POCO_NO_SOO
+
+
+ Any(): _pHolder(0)
+ /// Creates an empty any type.
+ {
+ }
+
+ template
+ Any(const ValueType& value):
+ _pHolder(new Holder(value))
+ /// Creates an any which stores the init parameter inside.
+ ///
+ /// Example:
+ /// Any a(13);
+ /// Any a(string("12345"));
+ {
+ }
+
+ Any(const Any& other):
+ _pHolder(other._pHolder ? other._pHolder->clone() : 0)
+ /// Copy constructor, works with both empty and initialized Any values.
+ {
+ }
+
+ ~Any()
+ {
+ delete _pHolder;
+ }
+
+ Any& swap(Any& rhs)
+ /// Swaps the content of the two Anys.
+ {
+ std::swap(_pHolder, rhs._pHolder);
+ return *this;
+ }
+
+ template
+ Any& operator = (const ValueType& rhs)
+ /// Assignment operator for all types != Any.
+ ///
+ /// Example:
+ /// Any a = 13;
+ /// Any a = string("12345");
+ {
+ Any(rhs).swap(*this);
+ return *this;
+ }
+
+ Any& operator = (const Any& rhs)
+ /// Assignment operator for Any.
+ {
+ Any(rhs).swap(*this);
+ return *this;
+ }
+
+ bool empty() const
+ /// Returns true if the Any is empty.
+ {
+ return !_pHolder;
+ }
+
+ const std::type_info& type() const
+ /// Returns the type information of the stored content.
+ /// If the Any is empty typeid(void) is returned.
+ /// It is recommended to always query an Any for its type info before
+ /// trying to extract data via an AnyCast/RefAnyCast.
+ {
+ return _pHolder ? _pHolder->type() : typeid(void);
+ }
+
+private:
+ class ValueHolder
+ {
+ public:
+ virtual ~ValueHolder() = default;
+
+ virtual const std::type_info& type() const = 0;
+ virtual ValueHolder* clone() const = 0;
+ };
+
+ template
+ class Holder: public ValueHolder
+ {
+ public:
+ Holder(const ValueType& value):
+ _held(value)
+ {
+ }
+
+ virtual const std::type_info& type() const
+ {
+ return typeid(ValueType);
+ }
+
+ virtual ValueHolder* clone() const
+ {
+ return new Holder(_held);
+ }
+
+ ValueType _held;
+
+ private:
+ Holder & operator = (const Holder &);
+ };
+
+ ValueHolder* content() const
+ {
+ return _pHolder;
+ }
+
+private:
+ ValueHolder* _pHolder;
+
+#endif // POCO_NO_SOO
+
+ template
+ friend ValueType* AnyCast(Any*);
+
+ template
+ friend ValueType* UnsafeAnyCast(Any*);
+
+ template
+ friend const ValueType& RefAnyCast(const Any&);
+
+ template
+ friend ValueType& RefAnyCast(Any&);
+
+ template
+ friend ValueType AnyCast(Any&);
+};
+
+
+template
+ValueType* AnyCast(Any* operand)
+ /// AnyCast operator used to extract the ValueType from an Any*. Will return a pointer
+ /// to the stored value.
+ ///
+ /// Example Usage:
+ /// MyType* pTmp = AnyCast(pAny).
+ /// Will return NULL if the cast fails, i.e. types don't match.
+{
+ return operand && operand->type() == typeid(ValueType)
+ ? &static_cast*>(operand->content())->_held
+ : 0;
+}
+
+
+template
+const ValueType* AnyCast(const Any* operand)
+ /// AnyCast operator used to extract a const ValueType pointer from an const Any*. Will return a const pointer
+ /// to the stored value.
+ ///
+ /// Example Usage:
+ /// const MyType* pTmp = AnyCast(pAny).
+ /// Will return NULL if the cast fails, i.e. types don't match.
+{
+ return AnyCast(const_cast(operand));
+}
+
+
+template
+ValueType AnyCast(Any& operand)
+ /// AnyCast operator used to extract a copy of the ValueType from an Any&.
+ ///
+ /// Example Usage:
+ /// MyType tmp = AnyCast(anAny).
+ /// Will throw a BadCastException if the cast fails.
+ /// Do not use an AnyCast in combination with references, i.e. MyType& tmp = ... or const MyType& tmp = ...
+ /// Some compilers will accept this code although a copy is returned. Use the RefAnyCast in
+ /// these cases.
+{
+ typedef typename TypeWrapper::TYPE NonRef;
+
+ NonRef* result = AnyCast(&operand);
+ if (!result)
+ {
+ std::string s = "RefAnyCast: Failed to convert between Any types ";
+ if (operand._pHolder)
+ {
+ s.append(1, '(');
+ s.append(operand._pHolder->type().name());
+ s.append(" => ");
+ s.append(typeid(ValueType).name());
+ s.append(1, ')');
+ }
+ throw BadCastException(s);
+ }
+ return *result;
+}
+
+
+template
+ValueType AnyCast(const Any& operand)
+ /// AnyCast operator used to extract a copy of the ValueType from an const Any&.
+ ///
+ /// Example Usage:
+ /// MyType tmp = AnyCast(anAny).
+ /// Will throw a BadCastException if the cast fails.
+ /// Do not use an AnyCast in combination with references, i.e. MyType& tmp = ... or const MyType& = ...
+ /// Some compilers will accept this code although a copy is returned. Use the RefAnyCast in
+ /// these cases.
+{
+ typedef typename TypeWrapper::TYPE NonRef;
+
+ return AnyCast(const_cast(operand));
+}
+
+
+template
+const ValueType& RefAnyCast(const Any & operand)
+ /// AnyCast operator used to return a const reference to the internal data.
+ ///
+ /// Example Usage:
+ /// const MyType& tmp = RefAnyCast(anAny);
+{
+ ValueType* result = AnyCast(const_cast(&operand));
+ if (!result)
+ {
+ std::string s = "RefAnyCast: Failed to convert between Any types ";
+ if (operand._pHolder)
+ {
+ s.append(1, '(');
+ s.append(operand._pHolder->type().name());
+ s.append(" => ");
+ s.append(typeid(ValueType).name());
+ s.append(1, ')');
+ }
+ throw BadCastException(s);
+ }
+ return *result;
+}
+
+
+template
+ValueType& RefAnyCast(Any& operand)
+ /// AnyCast operator used to return a reference to the internal data.
+ ///
+ /// Example Usage:
+ /// MyType& tmp = RefAnyCast(anAny);
+{
+ ValueType* result = AnyCast(&operand);
+ if (!result)
+ {
+ std::string s = "RefAnyCast: Failed to convert between Any types ";
+ if (operand._pHolder)
+ {
+ s.append(1, '(');
+ s.append(operand._pHolder->type().name());
+ s.append(" => ");
+ s.append(typeid(ValueType).name());
+ s.append(1, ')');
+ }
+ throw BadCastException(s);
+ }
+ return *result;
+}
+
+
+template
+ValueType* UnsafeAnyCast(Any* operand)
+ /// The "unsafe" versions of AnyCast are not part of the
+ /// public interface and may be removed at any time. They are
+ /// required where we know what type is stored in the any and can't
+ /// use typeid() comparison, e.g., when our types may travel across
+ /// different shared libraries.
+{
+ return &static_cast*>(operand->content())->_held;
+}
+
+
+template
+const ValueType* UnsafeAnyCast(const Any* operand)
+ /// The "unsafe" versions of AnyCast are not part of the
+ /// public interface and may be removed at any time. They are
+ /// required where we know what type is stored in the any and can't
+ /// use typeid() comparison, e.g., when our types may travel across
+ /// different shared libraries.
+{
+ return AnyCast(const_cast(operand));
+}
+
+
+} // namespace Poco
+
+
+#endif
diff --git a/include/Poco/Poco/Ascii.h b/include/Poco/Poco/Ascii.h
new file mode 100644
index 00000000..e7a8b855
--- /dev/null
+++ b/include/Poco/Poco/Ascii.h
@@ -0,0 +1,229 @@
+//
+// Ascii.h
+//
+// Library: Foundation
+// Package: Core
+// Module: Ascii
+//
+// Definition of the Ascii class.
+//
+// Copyright (c) 2010, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Ascii_INCLUDED
+#define Foundation_Ascii_INCLUDED
+
+
+#include "Poco/Foundation.h"
+
+
+namespace Poco {
+
+
+class Foundation_API Ascii
+ /// This class contains enumerations and static
+ /// utility functions for dealing with ASCII characters
+ /// and their properties.
+ ///
+ /// The classification functions will also work if
+ /// non-ASCII character codes are passed to them,
+ /// but classification will only check for
+ /// ASCII characters.
+ ///
+ /// This allows the classification methods to be used
+ /// on the single bytes of a UTF-8 string, without
+ /// causing assertions or inconsistent results (depending
+ /// upon the current locale) on bytes outside the ASCII range,
+ /// as may be produced by Ascii::isSpace(), etc.
+{
+public:
+ enum CharacterProperties
+ /// ASCII character properties.
+ {
+ ACP_CONTROL = 0x0001,
+ ACP_SPACE = 0x0002,
+ ACP_PUNCT = 0x0004,
+ ACP_DIGIT = 0x0008,
+ ACP_HEXDIGIT = 0x0010,
+ ACP_ALPHA = 0x0020,
+ ACP_LOWER = 0x0040,
+ ACP_UPPER = 0x0080,
+ ACP_GRAPH = 0x0100,
+ ACP_PRINT = 0x0200
+ };
+
+ static int properties(int ch);
+ /// Return the ASCII character properties for the
+ /// character with the given ASCII value.
+ ///
+ /// If the character is outside the ASCII range
+ /// (0 .. 127), 0 is returned.
+
+ static bool hasSomeProperties(int ch, int properties);
+ /// Returns true if the given character is
+ /// within the ASCII range and has at least one of
+ /// the given properties.
+
+ static bool hasProperties(int ch, int properties);
+ /// Returns true if the given character is
+ /// within the ASCII range and has all of
+ /// the given properties.
+
+ static bool isAscii(int ch);
+ /// Returns true iff the given character code is within
+ /// the ASCII range (0 .. 127).
+
+ static bool isSpace(int ch);
+ /// Returns true iff the given character is a whitespace.
+
+ static bool isDigit(int ch);
+ /// Returns true iff the given character is a digit.
+
+ static bool isHexDigit(int ch);
+ /// Returns true iff the given character is a hexadecimal digit.
+
+ static bool isPunct(int ch);
+ /// Returns true iff the given character is a punctuation character.
+
+ static bool isAlpha(int ch);
+ /// Returns true iff the given character is an alphabetic character.
+
+ static bool isAlphaNumeric(int ch);
+ /// Returns true iff the given character is an alphabetic character.
+
+ static bool isLower(int ch);
+ /// Returns true iff the given character is a lowercase alphabetic
+ /// character.
+
+ static bool isUpper(int ch);
+ /// Returns true iff the given character is an uppercase alphabetic
+ /// character.
+
+ static bool isPrintable(int ch);
+ /// Returns true iff the given character is printable.
+
+ static int toLower(int ch);
+ /// If the given character is an uppercase character,
+ /// return its lowercase counterpart, otherwise return
+ /// the character.
+
+ static int toUpper(int ch);
+ /// If the given character is a lowercase character,
+ /// return its uppercase counterpart, otherwise return
+ /// the character.
+
+private:
+ static const int CHARACTER_PROPERTIES[128];
+};
+
+
+//
+// inlines
+//
+inline int Ascii::properties(int ch)
+{
+ if (isAscii(ch))
+ return CHARACTER_PROPERTIES[ch];
+ else
+ return 0;
+}
+
+
+inline bool Ascii::isAscii(int ch)
+{
+ return (static_cast(ch) & 0xFFFFFF80) == 0;
+}
+
+
+inline bool Ascii::hasProperties(int ch, int props)
+{
+ return (properties(ch) & props) == props;
+}
+
+
+inline bool Ascii::hasSomeProperties(int ch, int props)
+{
+ return (properties(ch) & props) != 0;
+}
+
+
+inline bool Ascii::isSpace(int ch)
+{
+ return hasProperties(ch, ACP_SPACE);
+}
+
+
+inline bool Ascii::isDigit(int ch)
+{
+ return hasProperties(ch, ACP_DIGIT);
+}
+
+
+inline bool Ascii::isHexDigit(int ch)
+{
+ return hasProperties(ch, ACP_HEXDIGIT);
+}
+
+
+inline bool Ascii::isPunct(int ch)
+{
+ return hasProperties(ch, ACP_PUNCT);
+}
+
+
+inline bool Ascii::isAlpha(int ch)
+{
+ return hasProperties(ch, ACP_ALPHA);
+}
+
+
+inline bool Ascii::isAlphaNumeric(int ch)
+{
+ return hasSomeProperties(ch, ACP_ALPHA | ACP_DIGIT);
+}
+
+
+inline bool Ascii::isLower(int ch)
+{
+ return hasProperties(ch, ACP_LOWER);
+}
+
+
+inline bool Ascii::isUpper(int ch)
+{
+ return hasProperties(ch, ACP_UPPER);
+}
+
+
+inline bool Ascii::isPrintable(int ch)
+{
+ return hasProperties(ch, ACP_PRINT);
+}
+
+
+inline int Ascii::toLower(int ch)
+{
+ if (isUpper(ch))
+ return ch + 32;
+ else
+ return ch;
+}
+
+
+inline int Ascii::toUpper(int ch)
+{
+ if (isLower(ch))
+ return ch - 32;
+ else
+ return ch;
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_Ascii_INCLUDED
diff --git a/include/Poco/Poco/AtomicCounter.h b/include/Poco/Poco/AtomicCounter.h
new file mode 100644
index 00000000..1377fd4c
--- /dev/null
+++ b/include/Poco/Poco/AtomicCounter.h
@@ -0,0 +1,133 @@
+//
+// AtomicCounter.h
+//
+// Library: Foundation
+// Package: Core
+// Module: AtomicCounter
+//
+// Definition of the AtomicCounter class.
+//
+// Copyright (c) 2009, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_AtomicCounter_INCLUDED
+#define Foundation_AtomicCounter_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include
+
+
+namespace Poco {
+
+
+class Foundation_API AtomicCounter
+ /// This class implements a simple counter, which
+ /// provides atomic operations that are safe to
+ /// use in a multithreaded environment.
+ ///
+ /// Typical usage of AtomicCounter is for implementing
+ /// reference counting and similar functionality.
+{
+public:
+ typedef int ValueType; /// The underlying integer type.
+
+ AtomicCounter();
+ /// Creates a new AtomicCounter and initializes it to zero.
+
+ explicit AtomicCounter(ValueType initialValue);
+ /// Creates a new AtomicCounter and initializes it with
+ /// the given value.
+
+ AtomicCounter(const AtomicCounter& counter);
+ /// Creates the counter by copying another one.
+
+ ~AtomicCounter();
+ /// Destroys the AtomicCounter.
+
+ AtomicCounter& operator = (const AtomicCounter& counter);
+ /// Assigns the value of another AtomicCounter.
+
+ AtomicCounter& operator = (ValueType value);
+ /// Assigns a value to the counter.
+
+ operator ValueType () const;
+ /// Converts the AtomicCounter to ValueType.
+
+ ValueType value() const;
+ /// Returns the value of the counter.
+
+ ValueType operator ++ (); // prefix
+ /// Increments the counter and returns the result.
+
+ ValueType operator ++ (int); // postfix
+ /// Increments the counter and returns the previous value.
+
+ ValueType operator -- (); // prefix
+ /// Decrements the counter and returns the result.
+
+ ValueType operator -- (int); // postfix
+ /// Decrements the counter and returns the previous value.
+
+ bool operator ! () const;
+ /// Returns true if the counter is zero, false otherwise.
+
+private:
+ std::atomic _counter;
+};
+
+
+//
+// inlines
+//
+
+inline AtomicCounter::operator AtomicCounter::ValueType () const
+{
+ return _counter.load();
+}
+
+
+inline AtomicCounter::ValueType AtomicCounter::value() const
+{
+ return _counter.load();
+}
+
+
+inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix
+{
+ return ++_counter;
+}
+
+
+inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix
+{
+ return _counter++;
+}
+
+
+inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix
+{
+ return --_counter;
+}
+
+
+inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix
+{
+ return _counter--;
+}
+
+
+inline bool AtomicCounter::operator ! () const
+{
+ return _counter.load() == 0;
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_AtomicCounter_INCLUDED
diff --git a/include/Poco/Poco/AutoPtr.h b/include/Poco/Poco/AutoPtr.h
new file mode 100644
index 00000000..8d6bbacd
--- /dev/null
+++ b/include/Poco/Poco/AutoPtr.h
@@ -0,0 +1,417 @@
+//
+// AutoPtr.h
+//
+// Library: Foundation
+// Package: Core
+// Module: AutoPtr
+//
+// Definition of the AutoPtr template class.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_AutoPtr_INCLUDED
+#define Foundation_AutoPtr_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Exception.h"
+#include
+#include
+
+
+namespace Poco {
+
+
+template
+class AutoPtr
+ /// AutoPtr is a "smart" pointer for classes implementing
+ /// reference counting based garbage collection.
+ /// To be usable with the AutoPtr template, a class must
+ /// implement the following behaviour:
+ /// A class must maintain a reference count.
+ /// The constructors of the object initialize the reference
+ /// count to one.
+ /// The class must implement a public duplicate() method:
+ /// void duplicate();
+ /// that increments the reference count by one.
+ /// The class must implement a public release() method:
+ /// void release()
+ /// that decrements the reference count by one, and,
+ /// if the reference count reaches zero, deletes the
+ /// object.
+ ///
+ /// AutoPtr works in the following way:
+ /// If an AutoPtr is assigned an ordinary pointer to
+ /// an object (via the constructor or the assignment operator),
+ /// it takes ownership of the object and the object's reference
+ /// count remains unchanged.
+ /// If the AutoPtr is assigned another AutoPtr, the
+ /// object's reference count is incremented by one by
+ /// calling duplicate() on its object.
+ /// The destructor of AutoPtr calls release() on its
+ /// object.
+ /// AutoPtr supports dereferencing with both the ->
+ /// and the * operator. An attempt to dereference a null
+ /// AutoPtr results in a NullPointerException being thrown.
+ /// AutoPtr also implements all relational operators.
+ /// Note that AutoPtr allows casting of its encapsulated data types.
+{
+public:
+ AutoPtr(): _ptr(nullptr)
+ {
+ }
+
+ AutoPtr(C* ptr): _ptr(ptr)
+ {
+ }
+
+ AutoPtr(C* ptr, bool shared): _ptr(ptr)
+ {
+ if (shared && _ptr) _ptr->duplicate();
+ }
+
+ AutoPtr(const AutoPtr& ptr): _ptr(ptr._ptr)
+ {
+ if (_ptr) _ptr->duplicate();
+ }
+
+ AutoPtr(AutoPtr&& ptr) noexcept: _ptr(std::move(ptr._ptr))
+ {
+ ptr._ptr = nullptr;
+ }
+
+ template
+ AutoPtr(const AutoPtr& ptr): _ptr(const_cast(ptr.get()))
+ {
+ if (_ptr) _ptr->duplicate();
+ }
+
+ ~AutoPtr()
+ {
+ if (_ptr) _ptr->release();
+ }
+
+ AutoPtr& assign(C* ptr)
+ {
+ if (_ptr != ptr)
+ {
+ if (_ptr) _ptr->release();
+ _ptr = ptr;
+ }
+ return *this;
+ }
+
+ AutoPtr& assign(C* ptr, bool shared)
+ {
+ if (_ptr != ptr)
+ {
+ if (_ptr) _ptr->release();
+ _ptr = ptr;
+ if (shared && _ptr) _ptr->duplicate();
+ }
+ return *this;
+ }
+
+ AutoPtr& assign(const AutoPtr& ptr)
+ {
+ if (&ptr != this)
+ {
+ if (_ptr) _ptr->release();
+ _ptr = ptr._ptr;
+ if (_ptr) _ptr->duplicate();
+ }
+ return *this;
+ }
+
+ template
+ AutoPtr& assign(const AutoPtr& ptr)
+ {
+ if (ptr.get() != _ptr)
+ {
+ if (_ptr) _ptr->release();
+ _ptr = const_cast(ptr.get());
+ if (_ptr) _ptr->duplicate();
+ }
+ return *this;
+ }
+
+ void reset()
+ {
+ if (_ptr)
+ {
+ _ptr->release();
+ _ptr = nullptr;
+ }
+ }
+
+ void reset(C* ptr)
+ {
+ assign(ptr);
+ }
+
+ void reset(C* ptr, bool shared)
+ {
+ assign(ptr, shared);
+ }
+
+ void reset(const AutoPtr& ptr)
+ {
+ assign(ptr);
+ }
+
+ template
+ void reset(const AutoPtr& ptr)
+ {
+ assign(ptr);
+ }
+
+ AutoPtr& operator = (C* ptr)
+ {
+ return assign(ptr);
+ }
+
+ AutoPtr& operator = (const AutoPtr& ptr)
+ {
+ return assign(ptr);
+ }
+
+ AutoPtr& operator = (AutoPtr&& ptr) noexcept
+ {
+ if (_ptr) _ptr->release();
+ _ptr = ptr._ptr;
+ ptr._ptr = nullptr;
+ return *this;
+ }
+
+ template
+ AutoPtr& operator = (const AutoPtr& ptr)
+ {
+ return assign(ptr);
+ }
+
+ void swap(AutoPtr& ptr)
+ {
+ std::swap(_ptr, ptr._ptr);
+ }
+
+ template
+ AutoPtr cast() const
+ /// Casts the AutoPtr via a dynamic cast to the given type.
+ /// Returns an AutoPtr containing NULL if the cast fails.
+ /// Example: (assume class Sub: public Super)
+ /// AutoPtr super(new Sub());
+ /// AutoPtr sub = super.cast();
+ /// poco_assert (sub.get());
+ {
+ Other* pOther = dynamic_cast(_ptr);
+ return AutoPtr(pOther, true);
+ }
+
+ template
+ AutoPtr unsafeCast() const
+ /// Casts the AutoPtr via a static cast to the given type.
+ /// Example: (assume class Sub: public Super)
+ /// AutoPtr super(new Sub());
+ /// AutoPtr sub = super.unsafeCast();
+ /// poco_assert (sub.get());
+ {
+ Other* pOther = static_cast(_ptr);
+ return AutoPtr(pOther, true);
+ }
+
+ C* operator -> ()
+ {
+ if (_ptr)
+ return _ptr;
+ else
+ throw NullPointerException();
+ }
+
+ const C* operator -> () const
+ {
+ if (_ptr)
+ return _ptr;
+ else
+ throw NullPointerException();
+ }
+
+ C& operator * ()
+ {
+ if (_ptr)
+ return *_ptr;
+ else
+ throw NullPointerException();
+ }
+
+ const C& operator * () const
+ {
+ if (_ptr)
+ return *_ptr;
+ else
+ throw NullPointerException();
+ }
+
+ C* get()
+ {
+ return _ptr;
+ }
+
+ const C* get() const
+ {
+ return _ptr;
+ }
+
+ operator C* ()
+ {
+ return _ptr;
+ }
+
+ operator const C* () const
+ {
+ return _ptr;
+ }
+
+ bool operator ! () const
+ {
+ return _ptr == nullptr;
+ }
+
+ bool isNull() const
+ {
+ return _ptr == nullptr;
+ }
+
+ C* duplicate()
+ {
+ if (_ptr) _ptr->duplicate();
+ return _ptr;
+ }
+
+ bool operator == (const AutoPtr& ptr) const
+ {
+ return _ptr == ptr._ptr;
+ }
+
+ bool operator == (const C* ptr) const
+ {
+ return _ptr == ptr;
+ }
+
+ bool operator == (C* ptr) const
+ {
+ return _ptr == ptr;
+ }
+
+ bool operator == (std::nullptr_t ptr) const
+ {
+ return _ptr == ptr;
+ }
+
+ bool operator != (const AutoPtr& ptr) const
+ {
+ return _ptr != ptr._ptr;
+ }
+
+ bool operator != (const C* ptr) const
+ {
+ return _ptr != ptr;
+ }
+
+ bool operator != (C* ptr) const
+ {
+ return _ptr != ptr;
+ }
+
+ bool operator != (std::nullptr_t ptr) const
+ {
+ return _ptr != ptr;
+ }
+
+ bool operator < (const AutoPtr& ptr) const
+ {
+ return _ptr < ptr._ptr;
+ }
+
+ bool operator < (const C* ptr) const
+ {
+ return _ptr < ptr;
+ }
+
+ bool operator < (C* ptr) const
+ {
+ return _ptr < ptr;
+ }
+
+ bool operator <= (const AutoPtr& ptr) const
+ {
+ return _ptr <= ptr._ptr;
+ }
+
+ bool operator <= (const C* ptr) const
+ {
+ return _ptr <= ptr;
+ }
+
+ bool operator <= (C* ptr) const
+ {
+ return _ptr <= ptr;
+ }
+
+ bool operator > (const AutoPtr& ptr) const
+ {
+ return _ptr > ptr._ptr;
+ }
+
+ bool operator > (const C* ptr) const
+ {
+ return _ptr > ptr;
+ }
+
+ bool operator > (C* ptr) const
+ {
+ return _ptr > ptr;
+ }
+
+ bool operator >= (const AutoPtr& ptr) const
+ {
+ return _ptr >= ptr._ptr;
+ }
+
+ bool operator >= (const C* ptr) const
+ {
+ return _ptr >= ptr;
+ }
+
+ bool operator >= (C* ptr) const
+ {
+ return _ptr >= ptr;
+ }
+
+private:
+ C* _ptr;
+};
+
+
+template
+inline void swap(AutoPtr& p1, AutoPtr& p2)
+{
+ p1.swap(p2);
+}
+
+
+template
+AutoPtr makeAuto(Args&&... args)
+{
+ return AutoPtr(new T(std::forward(args)...));
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_AutoPtr_INCLUDED
diff --git a/include/Poco/Poco/BasicEvent.h b/include/Poco/Poco/BasicEvent.h
new file mode 100644
index 00000000..47e37dbd
--- /dev/null
+++ b/include/Poco/Poco/BasicEvent.h
@@ -0,0 +1,60 @@
+//
+// BasicEvent.h
+//
+// Library: Foundation
+// Package: Events
+// Module: BasicEvent
+//
+// Implementation of the BasicEvent template.
+//
+// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_BasicEvent_INCLUDED
+#define Foundation_BasicEvent_INCLUDED
+
+
+#include "Poco/AbstractEvent.h"
+#include "Poco/DefaultStrategy.h"
+#include "Poco/AbstractDelegate.h"
+#include "Poco/Mutex.h"
+
+
+namespace Poco {
+
+
+template
+class BasicEvent: public AbstractEvent <
+ TArgs, DefaultStrategy>,
+ AbstractDelegate,
+ TMutex
+>
+ /// A BasicEvent uses the DefaultStrategy which
+ /// invokes delegates in the order they have been registered.
+ ///
+ /// Please see the AbstractEvent class template documentation
+ /// for more information.
+{
+public:
+ BasicEvent()
+ {
+ }
+
+ ~BasicEvent()
+ {
+ }
+
+private:
+ BasicEvent(const BasicEvent& e);
+ BasicEvent& operator = (const BasicEvent& e);
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_BasicEvent_INCLUDED
diff --git a/include/Poco/Poco/BinaryReader.h b/include/Poco/Poco/BinaryReader.h
new file mode 100644
index 00000000..5b5e7bee
--- /dev/null
+++ b/include/Poco/Poco/BinaryReader.h
@@ -0,0 +1,265 @@
+//
+// BinaryReader.h
+//
+// Library: Foundation
+// Package: Streams
+// Module: BinaryReaderWriter
+//
+// Definition of the BinaryReader class.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_BinaryReader_INCLUDED
+#define Foundation_BinaryReader_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Buffer.h"
+#include "Poco/MemoryStream.h"
+#include
+#include
+
+
+namespace Poco {
+
+
+class TextEncoding;
+class TextConverter;
+
+
+class Foundation_API BinaryReader
+ /// This class reads basic types (and std::vectors thereof)
+ /// in binary form into an input stream.
+ /// It provides an extractor-based interface similar to istream.
+ /// The reader also supports automatic conversion from big-endian
+ /// (network byte order) to little-endian and vice-versa.
+ /// Use a BinaryWriter to create a stream suitable for a BinaryReader.
+{
+public:
+ enum StreamByteOrder
+ {
+ NATIVE_BYTE_ORDER = 1, /// the host's native byte-order
+ BIG_ENDIAN_BYTE_ORDER = 2, /// big-endian (network) byte-order
+ NETWORK_BYTE_ORDER = 2, /// big-endian (network) byte-order
+ LITTLE_ENDIAN_BYTE_ORDER = 3, /// little-endian byte-order
+ UNSPECIFIED_BYTE_ORDER = 4 /// unknown, byte-order will be determined by reading the byte-order mark
+ };
+
+ BinaryReader(std::istream& istr, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER);
+ /// Creates the BinaryReader.
+
+ BinaryReader(std::istream& istr, TextEncoding& encoding, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER);
+ /// Creates the BinaryReader using the given TextEncoding.
+ ///
+ /// Strings will be converted from the specified encoding
+ /// to the currently set global encoding (see Poco::TextEncoding::global()).
+
+ ~BinaryReader();
+ /// Destroys the BinaryReader.
+
+ BinaryReader& operator >> (bool& value);
+ BinaryReader& operator >> (char& value);
+ BinaryReader& operator >> (unsigned char& value);
+ BinaryReader& operator >> (signed char& value);
+ BinaryReader& operator >> (short& value);
+ BinaryReader& operator >> (unsigned short& value);
+ BinaryReader& operator >> (int& value);
+ BinaryReader& operator >> (unsigned int& value);
+ BinaryReader& operator >> (long& value);
+ BinaryReader& operator >> (unsigned long& value);
+ BinaryReader& operator >> (float& value);
+ BinaryReader& operator >> (double& value);
+
+#if defined(POCO_HAVE_INT64)
+ BinaryReader& operator >> (long long& value);
+ BinaryReader& operator >> (unsigned long long& value);
+#endif
+
+ BinaryReader& operator >> (std::string& value);
+
+ template
+ BinaryReader& operator >> (std::vector& value)
+ {
+ Poco::UInt32 size(0);
+ T elem;
+
+ *this >> size;
+ if (!good()) return *this;
+ value.reserve(size);
+ while (this->good() && size-- > 0)
+ {
+ *this >> elem;
+ value.push_back(elem);
+ }
+ return *this;
+ }
+
+ void read7BitEncoded(UInt32& value);
+ /// Reads a 32-bit unsigned integer in compressed format.
+ /// See BinaryWriter::write7BitEncoded() for a description
+ /// of the compression algorithm.
+
+#if defined(POCO_HAVE_INT64)
+ void read7BitEncoded(UInt64& value);
+ /// Reads a 64-bit unsigned integer in compressed format.
+ /// See BinaryWriter::write7BitEncoded() for a description
+ /// of the compression algorithm.
+#endif
+
+ void readRaw(std::streamsize length, std::string& value);
+ /// Reads length bytes of raw data into value.
+
+ void readRaw(char* buffer, std::streamsize length);
+ /// Reads length bytes of raw data into buffer.
+
+ void readBOM();
+ /// Reads a byte-order mark from the stream and configures
+ /// the reader for the encountered byte order.
+ /// A byte-order mark is a 16-bit integer with a value of 0xFEFF,
+ /// written in host byte order.
+
+ bool good();
+ /// Returns _istr.good();
+
+ bool fail();
+ /// Returns _istr.fail();
+
+ bool bad();
+ /// Returns _istr.bad();
+
+ bool eof();
+ /// Returns _istr.eof();
+
+ std::istream& stream() const;
+ /// Returns the underlying stream.
+
+ StreamByteOrder byteOrder() const;
+ /// Returns the byte-order used by the reader, which is
+ /// either BIG_ENDIAN_BYTE_ORDER or LITTLE_ENDIAN_BYTE_ORDER.
+
+ void setExceptions(std::ios_base::iostate st = (std::istream::failbit | std::istream::badbit));
+ /// Sets the stream to throw exception on specified state (default failbit and badbit);
+
+ std::streamsize available() const;
+ /// Returns the number of available bytes in the stream.
+
+private:
+ std::istream& _istr;
+ bool _flipBytes;
+ TextConverter* _pTextConverter;
+};
+
+
+template
+class BasicMemoryBinaryReader : public BinaryReader
+ /// A convenient wrapper for using Buffer and MemoryStream with BinaryReader.
+{
+public:
+ BasicMemoryBinaryReader(const Buffer& data, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
+ BinaryReader(_istr, byteOrder),
+ _data(data),
+ _istr(data.begin(), data.capacity())
+ {
+ }
+
+ BasicMemoryBinaryReader(const Buffer& data, TextEncoding& encoding, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
+ BinaryReader(_istr, encoding, byteOrder),
+ _data(data),
+ _istr(data.begin(), data.capacity())
+ {
+ }
+
+ ~BasicMemoryBinaryReader()
+ {
+ }
+
+ const Buffer& data() const
+ {
+ return _data;
+ }
+
+ const MemoryInputStream& stream() const
+ {
+ return _istr;
+ }
+
+ MemoryInputStream& stream()
+ {
+ return _istr;
+ }
+
+private:
+ const Buffer& _data;
+ MemoryInputStream _istr;
+};
+
+
+typedef BasicMemoryBinaryReader MemoryBinaryReader;
+
+
+//
+// inlines
+//
+
+
+inline bool BinaryReader::good()
+{
+ return _istr.good();
+}
+
+
+inline bool BinaryReader::fail()
+{
+ return _istr.fail();
+}
+
+
+inline bool BinaryReader::bad()
+{
+ return _istr.bad();
+}
+
+
+inline bool BinaryReader::eof()
+{
+ return _istr.eof();
+}
+
+
+inline std::istream& BinaryReader::stream() const
+{
+ return _istr;
+}
+
+
+inline BinaryReader::StreamByteOrder BinaryReader::byteOrder() const
+{
+#if defined(POCO_ARCH_BIG_ENDIAN)
+ return _flipBytes ? LITTLE_ENDIAN_BYTE_ORDER : BIG_ENDIAN_BYTE_ORDER;
+#else
+ return _flipBytes ? BIG_ENDIAN_BYTE_ORDER : LITTLE_ENDIAN_BYTE_ORDER;
+#endif
+}
+
+
+inline void BinaryReader::setExceptions(std::ios_base::iostate st)
+{
+ _istr.exceptions(st);
+}
+
+
+inline std::streamsize BinaryReader::available() const
+{
+ return _istr.rdbuf()->in_avail();
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_BinaryReader_INCLUDED
diff --git a/include/Poco/Poco/BinaryWriter.h b/include/Poco/Poco/BinaryWriter.h
new file mode 100644
index 00000000..98538429
--- /dev/null
+++ b/include/Poco/Poco/BinaryWriter.h
@@ -0,0 +1,269 @@
+//
+// BinaryWriter.h
+//
+// Library: Foundation
+// Package: Streams
+// Module: BinaryReaderWriter
+//
+// Definition of the BinaryWriter class.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_BinaryWriter_INCLUDED
+#define Foundation_BinaryWriter_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Buffer.h"
+#include "Poco/MemoryStream.h"
+#include
+#include
+
+
+namespace Poco {
+
+
+class TextEncoding;
+class TextConverter;
+
+
+class Foundation_API BinaryWriter
+ /// This class writes basic types (and std::vectors of these)
+ /// in binary form into an output stream.
+ /// It provides an inserter-based interface similar to ostream.
+ /// The writer also supports automatic conversion from big-endian
+ /// (network byte order) to little-endian and vice-versa.
+ /// Use a BinaryReader to read from a stream created by a BinaryWriter.
+ /// Be careful when exchanging data between systems with different
+ /// data type sizes (e.g., 32-bit and 64-bit architectures), as the sizes
+ /// of some of the basic types may be different. For example, writing a
+ /// long integer on a 64-bit system and reading it on a 32-bit system
+ /// may yield an incorrent result. Use fixed-size types (Int32, Int64, etc.)
+ /// in such a case.
+{
+public:
+ enum StreamByteOrder
+ {
+ NATIVE_BYTE_ORDER = 1, /// the host's native byte-order
+ BIG_ENDIAN_BYTE_ORDER = 2, /// big-endian (network) byte-order
+ NETWORK_BYTE_ORDER = 2, /// big-endian (network) byte-order
+ LITTLE_ENDIAN_BYTE_ORDER = 3 /// little-endian byte-order
+ };
+
+ BinaryWriter(std::ostream& ostr, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER);
+ /// Creates the BinaryWriter.
+
+ BinaryWriter(std::ostream& ostr, TextEncoding& encoding, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER);
+ /// Creates the BinaryWriter using the given TextEncoding.
+ ///
+ /// Strings will be converted from the currently set global encoding
+ /// (see Poco::TextEncoding::global()) to the specified encoding.
+
+ ~BinaryWriter();
+ /// Destroys the BinaryWriter.
+
+ BinaryWriter& operator << (bool value);
+ BinaryWriter& operator << (char value);
+ BinaryWriter& operator << (unsigned char value);
+ BinaryWriter& operator << (signed char value);
+ BinaryWriter& operator << (short value);
+ BinaryWriter& operator << (unsigned short value);
+ BinaryWriter& operator << (int value);
+ BinaryWriter& operator << (unsigned int value);
+ BinaryWriter& operator << (long value);
+ BinaryWriter& operator << (unsigned long value);
+ BinaryWriter& operator << (float value);
+ BinaryWriter& operator << (double value);
+
+#if defined(POCO_HAVE_INT64)
+ BinaryWriter& operator << (long long value);
+ BinaryWriter& operator << (unsigned long long value);
+#endif
+
+ BinaryWriter& operator << (const std::string& value);
+ BinaryWriter& operator << (const char* value);
+
+ template
+ BinaryWriter& operator << (const std::vector& value)
+ {
+ Poco::UInt32 size(static_cast(value.size()));
+
+ *this << size;
+ for (const auto& v: value)
+ {
+ *this << v;
+ }
+
+ return *this;
+ }
+
+ void write7BitEncoded(UInt32 value);
+ /// Writes a 32-bit unsigned integer in a compressed format.
+ /// The value is written out seven bits at a time, starting
+ /// with the seven least-significant bits.
+ /// The high bit of a byte indicates whether there are more bytes to be
+ /// written after this one.
+ /// If value will fit in seven bits, it takes only one byte of space.
+ /// If value will not fit in seven bits, the high bit is set on the first byte and
+ /// written out. value is then shifted by seven bits and the next byte is written.
+ /// This process is repeated until the entire integer has been written.
+
+#if defined(POCO_HAVE_INT64)
+ void write7BitEncoded(UInt64 value);
+ /// Writes a 64-bit unsigned integer in a compressed format.
+ /// The value written out seven bits at a time, starting
+ /// with the seven least-significant bits.
+ /// The high bit of a byte indicates whether there are more bytes to be
+ /// written after this one.
+ /// If value will fit in seven bits, it takes only one byte of space.
+ /// If value will not fit in seven bits, the high bit is set on the first byte and
+ /// written out. value is then shifted by seven bits and the next byte is written.
+ /// This process is repeated until the entire integer has been written.
+#endif
+
+ void writeRaw(const std::string& rawData);
+ /// Writes the string as-is to the stream.
+
+ void writeRaw(const char* buffer, std::streamsize length);
+ /// Writes length raw bytes from the given buffer to the stream.
+
+ void writeBOM();
+ /// Writes a byte-order mark to the stream. A byte order mark is
+ /// a 16-bit integer with a value of 0xFEFF, written in host byte-order.
+ /// A BinaryReader uses the byte-order mark to determine the byte-order
+ /// of the stream.
+
+ void flush();
+ /// Flushes the underlying stream.
+
+ bool good();
+ /// Returns _ostr.good();
+
+ bool fail();
+ /// Returns _ostr.fail();
+
+ bool bad();
+ /// Returns _ostr.bad();
+
+ std::ostream& stream() const;
+ /// Returns the underlying stream.
+
+ StreamByteOrder byteOrder() const;
+ /// Returns the byte ordering used by the writer, which is
+ /// either BIG_ENDIAN_BYTE_ORDER or LITTLE_ENDIAN_BYTE_ORDER.
+
+private:
+ std::ostream& _ostr;
+ bool _flipBytes;
+ TextConverter* _pTextConverter;
+};
+
+
+template
+class BasicMemoryBinaryWriter: public BinaryWriter
+ /// A convenient wrapper for using Buffer and MemoryStream with BinarWriter.
+{
+public:
+ BasicMemoryBinaryWriter(Buffer& data, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
+ BinaryWriter(_ostr, byteOrder),
+ _data(data),
+ _ostr(data.begin(), data.capacity())
+ {
+ }
+
+ BasicMemoryBinaryWriter(Buffer& data, TextEncoding& encoding, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
+ BinaryWriter(_ostr, encoding, byteOrder),
+ _data(data),
+ _ostr(data.begin(), data.capacity())
+ {
+ }
+
+ ~BasicMemoryBinaryWriter()
+ {
+ try
+ {
+ flush();
+ }
+ catch (...)
+ {
+ poco_unexpected();
+ }
+ }
+
+ Buffer& data()
+ {
+ return _data;
+ }
+
+ const Buffer& data() const
+ {
+ return _data;
+ }
+
+ const MemoryOutputStream& stream() const
+ {
+ return _ostr;
+ }
+
+ MemoryOutputStream& stream()
+ {
+ return _ostr;
+ }
+
+private:
+ Buffer& _data;
+ MemoryOutputStream _ostr;
+};
+
+
+typedef BasicMemoryBinaryWriter MemoryBinaryWriter;
+
+
+//
+// inlines
+//
+
+
+inline std::ostream& BinaryWriter::stream() const
+{
+ return _ostr;
+}
+
+
+inline bool BinaryWriter::good()
+{
+ return _ostr.good();
+}
+
+
+inline bool BinaryWriter::fail()
+{
+ return _ostr.fail();
+}
+
+
+inline bool BinaryWriter::bad()
+{
+ return _ostr.bad();
+}
+
+
+inline BinaryWriter::StreamByteOrder BinaryWriter::byteOrder() const
+{
+#if defined(POCO_ARCH_BIG_ENDIAN)
+ return _flipBytes ? LITTLE_ENDIAN_BYTE_ORDER : BIG_ENDIAN_BYTE_ORDER;
+#else
+ return _flipBytes ? BIG_ENDIAN_BYTE_ORDER : LITTLE_ENDIAN_BYTE_ORDER;
+#endif
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_BinaryWriter_INCLUDED
diff --git a/include/Poco/Poco/Buffer.h b/include/Poco/Poco/Buffer.h
new file mode 100644
index 00000000..87c59f16
--- /dev/null
+++ b/include/Poco/Poco/Buffer.h
@@ -0,0 +1,362 @@
+//
+// Buffer.h
+//
+// Library: Foundation
+// Package: Core
+// Module: Buffer
+//
+// Definition of the Buffer class.
+//
+// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Buffer_INCLUDED
+#define Foundation_Buffer_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Exception.h"
+#include
+#include
+
+
+namespace Poco {
+
+
+template
+class Buffer
+ /// A buffer class that allocates a buffer of a given type and size
+ /// in the constructor and deallocates the buffer in the destructor.
+ ///
+ /// This class is useful everywhere where a temporary buffer
+ /// is needed.
+{
+public:
+ Buffer(std::size_t length):
+ _capacity(length),
+ _used(length),
+ _ptr(0),
+ _ownMem(true)
+ /// Creates and allocates the Buffer.
+ {
+ if (length > 0)
+ {
+ _ptr = new T[length];
+ }
+ }
+
+ Buffer(T* pMem, std::size_t length):
+ _capacity(length),
+ _used(length),
+ _ptr(pMem),
+ _ownMem(false)
+ /// Creates the Buffer. Length argument specifies the length
+ /// of the supplied memory pointed to by pMem in the number
+ /// of elements of type T. Supplied pointer is considered
+ /// blank and not owned by Buffer, so in this case Buffer
+ /// only acts as a wrapper around externally supplied
+ /// (and lifetime-managed) memory.
+ {
+ }
+
+ Buffer(const T* pMem, std::size_t length):
+ _capacity(length),
+ _used(length),
+ _ptr(0),
+ _ownMem(true)
+ /// Creates and allocates the Buffer; copies the contents of
+ /// the supplied memory into the buffer. Length argument specifies
+ /// the length of the supplied memory pointed to by pMem in the
+ /// number of elements of type T.
+ {
+ if (_capacity > 0)
+ {
+ _ptr = new T[_capacity];
+ std::memcpy(_ptr, pMem, _used * sizeof(T));
+ }
+ }
+
+ Buffer(const Buffer& other):
+ /// Copy constructor.
+ _capacity(other._used),
+ _used(other._used),
+ _ptr(0),
+ _ownMem(true)
+ {
+ if (_used)
+ {
+ _ptr = new T[_used];
+ std::memcpy(_ptr, other._ptr, _used * sizeof(T));
+ }
+ }
+
+ Buffer(Buffer&& other) noexcept:
+ /// Move constructor.
+ _capacity(other._capacity),
+ _used(other._used),
+ _ptr(other._ptr),
+ _ownMem(other._ownMem)
+ {
+ other._capacity = 0;
+ other._used = 0;
+ other._ownMem = false;
+ other._ptr = nullptr;
+ }
+
+ Buffer& operator = (const Buffer& other)
+ /// Assignment operator.
+ {
+ if (this != &other)
+ {
+ Buffer tmp(other);
+ swap(tmp);
+ }
+
+ return *this;
+ }
+
+ Buffer& operator = (Buffer&& other) noexcept
+ /// Move assignment operator.
+ {
+ if (_ownMem) delete [] _ptr;
+
+ _capacity = other._capacity;
+ _used = other._used;
+ _ptr = other._ptr;
+ _ownMem = other._ownMem;
+
+ other._capacity = 0;
+ other._used = 0;
+ other._ownMem = false;
+ other._ptr = nullptr;
+
+ return *this;
+ }
+
+ ~Buffer()
+ /// Destroys the Buffer.
+ {
+ if (_ownMem) delete [] _ptr;
+ }
+
+ void resize(std::size_t newCapacity, bool preserveContent = true)
+ /// Resizes the buffer capacity and size. If preserveContent is true,
+ /// the content of the old buffer is copied over to the
+ /// new buffer. The new capacity can be larger or smaller than
+ /// the current one; if it is smaller, capacity will remain intact.
+ /// Size will always be set to the new capacity.
+ ///
+ /// Buffers only wrapping externally owned storage can not be
+ /// resized. If resize is attempted on those, IllegalAccessException
+ /// is thrown.
+ {
+ if (!_ownMem) throw Poco::InvalidAccessException("Cannot resize buffer which does not own its storage.");
+
+ if (newCapacity > _capacity)
+ {
+ T* ptr = new T[newCapacity];
+ if (preserveContent && _ptr)
+ {
+ std::memcpy(ptr, _ptr, _used * sizeof(T));
+ }
+ delete [] _ptr;
+ _ptr = ptr;
+ _capacity = newCapacity;
+ }
+
+ _used = newCapacity;
+ }
+
+ void setCapacity(std::size_t newCapacity, bool preserveContent = true)
+ /// Sets the buffer capacity. If preserveContent is true,
+ /// the content of the old buffer is copied over to the
+ /// new buffer. The new capacity can be larger or smaller than
+ /// the current one; size will be set to the new capacity only if
+ /// new capacity is smaller than the current size, otherwise it will
+ /// remain intact.
+ ///
+ /// Buffers only wrapping externally owned storage can not be
+ /// resized. If resize is attempted on those, IllegalAccessException
+ /// is thrown.
+ {
+ if (!_ownMem) throw Poco::InvalidAccessException("Cannot resize buffer which does not own its storage.");
+
+ if (newCapacity != _capacity)
+ {
+ T* ptr = 0;
+ if (newCapacity > 0)
+ {
+ ptr = new T[newCapacity];
+ if (preserveContent && _ptr)
+ {
+ std::size_t newSz = _used < newCapacity ? _used : newCapacity;
+ std::memcpy(ptr, _ptr, newSz * sizeof(T));
+ }
+ }
+ delete [] _ptr;
+ _ptr = ptr;
+ _capacity = newCapacity;
+
+ if (newCapacity < _used) _used = newCapacity;
+ }
+ }
+
+ void assign(const T* buf, std::size_t sz)
+ /// Assigns the argument buffer to this buffer.
+ /// If necessary, resizes the buffer.
+ {
+ if (0 == sz) return;
+ if (sz > _capacity) resize(sz, false);
+ std::memcpy(_ptr, buf, sz * sizeof(T));
+ _used = sz;
+ }
+
+ void append(const T* buf, std::size_t sz)
+ /// Resizes this buffer and appends the argument buffer.
+ {
+ if (0 == sz) return;
+ resize(_used + sz, true);
+ std::memcpy(_ptr + _used - sz, buf, sz * sizeof(T));
+ }
+
+ void append(T val)
+ /// Resizes this buffer by one element and appends the argument value.
+ {
+ resize(_used + 1, true);
+ _ptr[_used - 1] = val;
+ }
+
+ void append(const Buffer& buf)
+ /// Resizes this buffer and appends the argument buffer.
+ {
+ append(buf.begin(), buf.size());
+ }
+
+ std::size_t capacity() const
+ /// Returns the allocated memory size in elements.
+ {
+ return _capacity;
+ }
+
+ std::size_t capacityBytes() const
+ /// Returns the allocated memory size in bytes.
+ {
+ return _capacity * sizeof(T);
+ }
+
+ void swap(Buffer& other)
+ /// Swaps the buffer with another one.
+ {
+ using std::swap;
+
+ swap(_ptr, other._ptr);
+ swap(_capacity, other._capacity);
+ swap(_used, other._used);
+ swap(_ownMem, other._ownMem);
+ }
+
+ bool operator == (const Buffer& other) const
+ /// Compare operator.
+ {
+ if (this != &other)
+ {
+ if (_used == other._used)
+ {
+ if (_ptr && other._ptr && std::memcmp(_ptr, other._ptr, _used * sizeof(T)) == 0)
+ {
+ return true;
+ }
+ else return _used == 0;
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ bool operator != (const Buffer& other) const
+ /// Compare operator.
+ {
+ return !(*this == other);
+ }
+
+ void clear()
+ /// Sets the contents of the buffer to zero.
+ {
+ std::memset(_ptr, 0, _used * sizeof(T));
+ }
+
+ std::size_t size() const
+ /// Returns the used size of the buffer in elements.
+ {
+ return _used;
+ }
+
+ std::size_t sizeBytes() const
+ /// Returns the used size of the buffer in bytes.
+ {
+ return _used * sizeof(T);
+ }
+
+ T* begin()
+ /// Returns a pointer to the beginning of the buffer.
+ {
+ return _ptr;
+ }
+
+ const T* begin() const
+ /// Returns a pointer to the beginning of the buffer.
+ {
+ return _ptr;
+ }
+
+ T* end()
+ /// Returns a pointer to end of the buffer.
+ {
+ return _ptr + _used;
+ }
+
+ const T* end() const
+ /// Returns a pointer to the end of the buffer.
+ {
+ return _ptr + _used;
+ }
+
+ bool empty() const
+ /// Return true if buffer is empty.
+ {
+ return 0 == _used;
+ }
+
+ T& operator [] (std::size_t index)
+ {
+ poco_assert (index < _used);
+
+ return _ptr[index];
+ }
+
+ const T& operator [] (std::size_t index) const
+ {
+ poco_assert (index < _used);
+
+ return _ptr[index];
+ }
+
+private:
+ Buffer();
+
+ std::size_t _capacity;
+ std::size_t _used;
+ T* _ptr;
+ bool _ownMem;
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_Buffer_INCLUDED
diff --git a/include/Poco/Poco/Bugcheck.h b/include/Poco/Poco/Bugcheck.h
new file mode 100644
index 00000000..ca475b88
--- /dev/null
+++ b/include/Poco/Poco/Bugcheck.h
@@ -0,0 +1,206 @@
+//
+// Bugcheck.h
+//
+// Library: Foundation
+// Package: Core
+// Module: Bugcheck
+//
+// Definition of the Bugcheck class and the self-testing macros.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Bugcheck_INCLUDED
+#define Foundation_Bugcheck_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include
+#include
+#if defined(_DEBUG)
+# include
+#endif
+
+
+namespace Poco {
+
+
+class Foundation_API Bugcheck
+ /// This class provides some static methods that are
+ /// used by the
+ /// poco_assert_dbg(), poco_assert(), poco_check_ptr(),
+ /// poco_bugcheck() and poco_unexpected() macros.
+ /// You should not invoke these methods
+ /// directly. Use the macros instead, as they
+ /// automatically provide useful context information.
+{
+public:
+ static void assertion(const char* cond, const char* file, int line, const char* text = 0);
+ /// An assertion failed. Break into the debugger, if
+ /// possible, then throw an AssertionViolationException.
+
+ static void nullPointer(const char* ptr, const char* file, int line);
+ /// An null pointer was encountered. Break into the debugger, if
+ /// possible, then throw an NullPointerException.
+
+ static void bugcheck(const char* file, int line);
+ /// An internal error was encountered. Break into the debugger, if
+ /// possible, then throw an BugcheckException.
+
+ static void bugcheck(const char* msg, const char* file, int line);
+ /// An internal error was encountered. Break into the debugger, if
+ /// possible, then throw an BugcheckException.
+
+ static void unexpected(const char* file, int line);
+ /// An exception was caught in a destructor. Break into debugger,
+ /// if possible and report exception. Must only be called from
+ /// within a catch () block as it rethrows the exception to
+ /// determine its class.
+
+ static void debugger(const char* file, int line);
+ /// An internal error was encountered. Break into the debugger, if
+ /// possible.
+
+ static void debugger(const char* msg, const char* file, int line);
+ /// An internal error was encountered. Break into the debugger, if
+ /// possible.
+
+protected:
+ static std::string what(const char* msg, const char* file, int line, const char* text = 0);
+};
+
+
+} // namespace Poco
+
+
+//
+// useful macros (these automatically supply line number and file name)
+//
+#if defined(__KLOCWORK__) || defined(__clang_analyzer__)
+
+
+// Short-circuit these macros when under static analysis.
+// Ideally, static analysis tools should understand and reason correctly about
+// noreturn methods such as Bugcheck::bugcheck(). In practice, they don't.
+// Help them by turning these macros into std::abort() as described here:
+// https://developer.klocwork.com/documentation/en/insight/10-1/tuning-cc-analysis#Usingthe__KLOCWORK__macro
+
+#include // for abort
+#define poco_assert_dbg(cond) do { if (!(cond)) std::abort(); } while (0)
+#define poco_assert_msg_dbg(cond, text) do { if (!(cond)) std::abort(); } while (0)
+#define poco_assert(cond) do { if (!(cond)) std::abort(); } while (0)
+#define poco_assert_msg(cond, text) do { if (!(cond)) std::abort(); } while (0)
+#define poco_check_ptr(ptr) do { if (!(ptr)) std::abort(); } while (0)
+#define poco_bugcheck() do { std::abort(); } while (0)
+#define poco_bugcheck_msg(msg) do { std::abort(); } while (0)
+
+
+#else // defined(__KLOCWORK__) || defined(__clang_analyzer__)
+
+
+#if defined(_DEBUG)
+ #define poco_assert_dbg(cond) \
+ if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__); else (void) 0
+
+ #define poco_assert_msg_dbg(cond, text) \
+ if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__, text); else (void) 0
+#else
+ #define poco_assert_msg_dbg(cond, text)
+ #define poco_assert_dbg(cond)
+#endif
+
+
+#define poco_assert(cond) \
+ if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__); else (void) 0
+
+
+#define poco_assert_msg(cond, text) \
+ if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__, text); else (void) 0
+
+
+#define poco_check_ptr(ptr) \
+ if (!(ptr)) Poco::Bugcheck::nullPointer(#ptr, __FILE__, __LINE__); else (void) 0
+
+
+#define poco_bugcheck() \
+ Poco::Bugcheck::bugcheck(__FILE__, __LINE__)
+
+
+#define poco_bugcheck_msg(msg) \
+ Poco::Bugcheck::bugcheck(msg, __FILE__, __LINE__)
+
+
+#endif // defined(__KLOCWORK__) || defined(__clang_analyzer__)
+
+
+#define poco_unexpected() \
+ Poco::Bugcheck::unexpected(__FILE__, __LINE__);
+
+
+#define poco_debugger() \
+ Poco::Bugcheck::debugger(__FILE__, __LINE__)
+
+
+#define poco_debugger_msg(msg) \
+ Poco::Bugcheck::debugger(msg, __FILE__, __LINE__)
+
+
+#if defined(_DEBUG)
+# define poco_stdout_dbg(outstr) \
+ std::cout << __FILE__ << '(' << std::dec << __LINE__ << "):" << outstr << std::endl;
+#else
+# define poco_stdout_dbg(outstr)
+#endif
+
+
+#if defined(_DEBUG)
+# define poco_stderr_dbg(outstr) \
+ std::cerr << __FILE__ << '(' << std::dec << __LINE__ << "):" << outstr << std::endl;
+#else
+# define poco_stderr_dbg(outstr)
+#endif
+
+
+//
+// poco_static_assert
+//
+// The following was ported from
+//
+
+
+template
+struct POCO_STATIC_ASSERTION_FAILURE;
+
+
+template <>
+struct POCO_STATIC_ASSERTION_FAILURE
+{
+ enum
+ {
+ value = 1
+ };
+};
+
+
+template
+struct poco_static_assert_test
+{
+};
+
+
+#if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4))
+#define poco_static_assert(B) \
+ typedef char POCO_JOIN(poco_static_assert_typedef_, __LINE__) \
+ [POCO_STATIC_ASSERTION_FAILURE<(bool) (B)>::value]
+#else
+#define poco_static_assert(B) \
+ typedef poco_static_assert_test)> \
+ POCO_JOIN(poco_static_assert_typedef_, __LINE__) POCO_UNUSED
+#endif
+
+
+#endif // Foundation_Bugcheck_INCLUDED
diff --git a/include/Poco/Poco/Config.h b/include/Poco/Poco/Config.h
new file mode 100644
index 00000000..fb3cca8f
--- /dev/null
+++ b/include/Poco/Poco/Config.h
@@ -0,0 +1,202 @@
+//
+// Config.h
+//
+// Library: Foundation
+// Package: Core
+// Module: Foundation
+//
+// Feature configuration for the POCO libraries.
+//
+// Copyright (c) 2006-2016, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Config_INCLUDED
+#define Foundation_Config_INCLUDED
+
+
+// Define to disable implicit linking
+// #define POCO_NO_AUTOMATIC_LIBS
+
+
+// Define to disable automatic initialization
+// Defining this will disable ALL automatic
+// initialization framework-wide (e.g. Net
+// on Windows, all Data back-ends, etc).
+//
+// #define POCO_NO_AUTOMATIC_LIB_INIT
+
+
+// Define to disable FPEnvironment support
+// #define POCO_NO_FPENVIRONMENT
+
+
+// Define if std::wstring is not available
+// #define POCO_NO_WSTRING
+
+
+// Define to disable shared memory
+// #define POCO_NO_SHAREDMEMORY
+
+
+// Define if no header is available (such as on WinCE)
+// #define POCO_NO_LOCALE
+
+
+// Define to desired default thread stack size
+// Zero means OS default
+#ifndef POCO_THREAD_STACK_SIZE
+ #define POCO_THREAD_STACK_SIZE 0
+#endif
+
+
+// Define to override system-provided
+// minimum thread priority value on POSIX
+// platforms (returned by Poco::Thread::getMinOSPriority()).
+// #define POCO_THREAD_PRIORITY_MIN 0
+
+
+// Define to override system-provided
+// maximum thread priority value on POSIX
+// platforms (returned by Poco::Thread::getMaxOSPriority()).
+// #define POCO_THREAD_PRIORITY_MAX 31
+
+
+// Define to disable small object optimization. If not
+// defined, Any and Dynamic::Var (and similar optimization
+// candidates) will be auto-allocated on the stack in
+// cases when value holder fits into POCO_SMALL_OBJECT_SIZE
+// (see below).
+//
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// !!! NOTE: Any/Dynamic::Var SOO will NOT work reliably !!!
+// !!! without C++11 (std::aligned_storage in particular). !!!
+// !!! Only comment this out if your compiler has support !!!
+// !!! for std::aligned_storage. !!!
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//
+#ifndef POCO_ENABLE_SOO
+#define POCO_NO_SOO
+#endif
+
+
+// Small object size in bytes. When assigned to Any or Var,
+// objects larger than this value will be alocated on the heap,
+// while those smaller will be placement new-ed into an
+// internal buffer.
+#if !defined(POCO_SMALL_OBJECT_SIZE) && !defined(POCO_NO_SOO)
+ #define POCO_SMALL_OBJECT_SIZE 32
+#endif
+
+
+// Define to disable compilation of DirectoryWatcher
+// on platforms with no inotify.
+// #define POCO_NO_INOTIFY
+
+// Define to force the use of PollingDirectoryWatcher
+// #define POCO_DW_FORCE_POLLING
+
+
+// Following are options to remove certain features
+// to reduce library/executable size for smaller
+// embedded platforms. By enabling these options,
+// the size of a statically executable can be
+// reduced by a few 100 Kbytes.
+
+
+// No automatic registration of FileChannel in
+// LoggingFactory - avoids FileChannel and friends
+// being linked to executable.
+// #define POCO_NO_FILECHANNEL
+
+
+// No automatic registration of SplitterChannel in
+// LoggingFactory - avoids SplitterChannel being
+// linked to executable.
+// #define POCO_NO_SPLITTERCHANNEL
+
+
+// No automatic registration of SyslogChannel in
+// LoggingFactory - avoids SyslogChannel being
+// linked to executable on Unix/Linux systems.
+// #define POCO_NO_SYSLOGCHANNEL
+
+
+// Define to enable MSVC secure warnings
+// #define POCO_MSVC_SECURE_WARNINGS
+
+
+// No support for INI file configurations in
+// Poco::Util::Application.
+// #define POCO_UTIL_NO_INIFILECONFIGURATION
+
+
+// No support for JSON configuration in
+// Poco::Util::Application. Avoids linking of JSON
+// library and saves a few 100 Kbytes.
+// #define POCO_UTIL_NO_JSONCONFIGURATION
+
+
+// No support for XML configuration in
+// Poco::Util::Application. Avoids linking of XML
+// library and saves a few 100 Kbytes.
+// #define POCO_UTIL_NO_XMLCONFIGURATION
+
+
+// No IPv6 support
+// Define to disable IPv6
+// #define POCO_NET_NO_IPv6
+
+
+// Windows CE has no locale support
+#if defined(_WIN32_WCE)
+ #define POCO_NO_LOCALE
+#endif
+
+
+// Enable the poco_debug_* and poco_trace_* macros
+// even if the _DEBUG variable is not set.
+// This allows the use of these macros in a release version.
+// #define POCO_LOG_DEBUG
+
+
+// OpenSSL on Windows
+//
+// Poco has its own OpenSSL build system.
+// See
+// for details.
+//
+// These options are Windows only.
+//
+// To disable the use of Poco-provided OpenSSL binaries,
+// define POCO_EXTERNAL_OPENSSL.
+//
+// Possible values:
+// POCO_EXTERNAL_OPENSSL_SLPRO:
+// Automatically link OpenSSL libraries from OpenSSL Windows installer provided
+// by Shining Light Productions
+// The (global) library search path must be set accordingly.
+// POCO_EXTERNAL_OPENSSL_DEFAULT:
+// Automatically link OpenSSL libraries from standard OpenSSL Windows build.
+// The (global) library search path must be set accordingly.
+// empty or other value:
+// Do not link any OpenSSL libraries automatically. You will have to edit the
+// Visual C++ project files for Crypto and NetSSL_OpenSSL.
+#ifndef POCO_EXTERNAL_OPENSSL
+ #define POCO_EXTERNAL_OPENSSL POCO_EXTERNAL_OPENSSL_SLPRO
+#endif
+
+
+// Define to prevent changing the suffix for shared libraries
+// to "d.so", "d.dll", etc. for _DEBUG builds in Poco::SharedLibrary.
+// #define POCO_NO_SHARED_LIBRARY_DEBUG_SUFFIX
+
+
+// Disarm POCO_DEPRECATED macro.
+// #define POCO_NO_DEPRECATED
+
+
+#endif // Foundation_Config_INCLUDED
diff --git a/include/Poco/Poco/Crypto/Crypto.h b/include/Poco/Poco/Crypto/Crypto.h
new file mode 100644
index 00000000..de2babf6
--- /dev/null
+++ b/include/Poco/Poco/Crypto/Crypto.h
@@ -0,0 +1,191 @@
+//
+// Crypto.h
+//
+// Library: Crypto
+// Package: CryptoCore
+// Module: Crypto
+//
+// Basic definitions for the Poco Crypto library.
+// This file must be the first file included by every other Crypto
+// header file.
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_Crypto_INCLUDED
+#define Crypto_Crypto_INCLUDED
+
+
+#define POCO_EXTERNAL_OPENSSL_DEFAULT 1
+#define POCO_EXTERNAL_OPENSSL_SLPRO 2
+
+
+#include "Poco/Foundation.h"
+#include
+
+
+#ifndef OPENSSL_VERSION_PREREQ
+ #if defined(OPENSSL_VERSION_MAJOR) && defined(OPENSSL_VERSION_MINOR)
+ #define OPENSSL_VERSION_PREREQ(maj, min) \
+ ((OPENSSL_VERSION_MAJOR << 16) + OPENSSL_VERSION_MINOR >= ((maj) << 16) + (min))
+ #else
+ #define OPENSSL_VERSION_PREREQ(maj, min) \
+ (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | ((min) << 20)))
+ #endif
+#endif
+
+
+enum RSAPaddingMode
+ /// The padding mode used for RSA public key encryption.
+{
+ RSA_PADDING_PKCS1,
+ /// PKCS #1 v1.5 padding. This currently is the most widely used mode.
+
+ RSA_PADDING_PKCS1_OAEP,
+ /// EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty
+ /// encoding parameter. This mode is recommended for all new applications.
+
+ RSA_PADDING_NONE
+ /// Raw RSA encryption. This mode should only be used to implement cryptographically
+ /// sound padding modes in the application code. Encrypting user data directly with RSA
+ /// is insecure.
+};
+
+
+//
+// The following block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the Crypto_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// Crypto_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+//
+#if defined(_WIN32)
+ #if defined(POCO_DLL)
+ #if defined(Crypto_EXPORTS)
+ #define Crypto_API __declspec(dllexport)
+ #else
+ #define Crypto_API __declspec(dllimport)
+ #endif
+ #endif
+#endif
+
+
+#if !defined(Crypto_API)
+ #if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4)
+ #define Crypto_API __attribute__ ((visibility ("default")))
+ #else
+ #define Crypto_API
+ #endif
+#endif
+
+
+//
+// Automatically link Crypto and OpenSSL libraries.
+//
+#if defined(_MSC_VER)
+ #if !defined(POCO_NO_AUTOMATIC_LIBS)
+ #if defined(POCO_INTERNAL_OPENSSL_MSVC_VER)
+ #if defined(POCO_EXTERNAL_OPENSSL)
+ #pragma message("External OpenSSL defined but internal headers used - possible mismatch!")
+ #endif // POCO_EXTERNAL_OPENSSL
+ #if !defined(_DEBUG)
+ #define POCO_DEBUG_SUFFIX ""
+ #if !defined (_DLL)
+ #define POCO_STATIC_SUFFIX "mt"
+ #else // _DLL
+ #define POCO_STATIC_SUFFIX ""
+ #endif
+ #else // _DEBUG
+ #define POCO_DEBUG_SUFFIX "d"
+ #if !defined (_DLL)
+ #define POCO_STATIC_SUFFIX "mt"
+ #else // _DLL
+ #define POCO_STATIC_SUFFIX ""
+ #endif
+ #endif
+ #pragma comment(lib, "libcrypto" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
+ #pragma comment(lib, "libssl" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
+ #if !defined(_WIN64) && !defined (_DLL) && \
+ (POCO_INTERNAL_OPENSSL_MSVC_VER == 120) && \
+ (POCO_MSVC_VERSION < POCO_INTERNAL_OPENSSL_MSVC_VER)
+ #pragma comment(lib, "libPreVS2013CRT" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
+ #endif
+ #if !defined (_DLL) && (POCO_MSVS_VERSION >= 2015)
+ #pragma comment(lib, "legacy_stdio_definitions.lib")
+ #pragma comment(lib, "legacy_stdio_wide_specifiers.lib")
+ #endif
+ #elif defined(POCO_EXTERNAL_OPENSSL)
+ #if POCO_EXTERNAL_OPENSSL == POCO_EXTERNAL_OPENSSL_SLPRO
+ #if defined(POCO_DLL)
+ #if OPENSSL_VERSION_PREREQ(1,1)
+ #pragma comment(lib, "libcrypto.lib")
+ #pragma comment(lib, "libssl.lib")
+ #else
+ #pragma comment(lib, "libeay32.lib")
+ #pragma comment(lib, "ssleay32.lib")
+ #endif
+ #else
+ #if OPENSSL_VERSION_PREREQ(1,1)
+ #if defined(_WIN64)
+ #pragma comment(lib, "libcrypto")
+ #pragma comment(lib, "libssl")
+ #else
+ #pragma comment(lib, "libcrypto32" POCO_LIB_SUFFIX)
+ #pragma comment(lib, "libssl32" POCO_LIB_SUFFIX)
+ #endif
+ #else
+ #pragma comment(lib, "libeay32" POCO_LIB_SUFFIX)
+ #pragma comment(lib, "ssleay32" POCO_LIB_SUFFIX)
+ #endif
+ #endif
+ #elif POCO_EXTERNAL_OPENSSL == POCO_EXTERNAL_OPENSSL_DEFAULT
+ #if OPENSSL_VERSION_PREREQ(1,1)
+ #pragma comment(lib, "libcrypto.lib")
+ #pragma comment(lib, "libssl.lib")
+ #else
+ #pragma comment(lib, "libeay32.lib")
+ #pragma comment(lib, "ssleay32.lib")
+ #endif
+ #endif
+ #endif // POCO_INTERNAL_OPENSSL_MSVC_VER
+ #if !defined(Crypto_EXPORTS)
+ #pragma comment(lib, "PocoCrypto" POCO_LIB_SUFFIX)
+ #endif
+ #endif // POCO_NO_AUTOMATIC_LIBS
+#endif
+
+
+namespace Poco {
+namespace Crypto {
+
+
+void Crypto_API initializeCrypto();
+ /// Initialize the Crypto library, as well as the underlying OpenSSL
+ /// libraries, by calling OpenSSLInitializer::initialize().
+ ///
+ /// Should be called before using any class from the Crypto library.
+ /// The Crypto library will be initialized automatically, through
+ /// OpenSSLInitializer instances held by various Crypto classes
+ /// (Cipher, CipherKey, RSAKey, X509Certificate).
+ /// However, it is recommended to call initializeCrypto()
+ /// in any case at application startup.
+ ///
+ /// Can be called multiple times; however, for every call to
+ /// initializeCrypto(), a matching call to uninitializeCrypto()
+ /// must be performed.
+
+
+void Crypto_API uninitializeCrypto();
+ /// Uninitializes the Crypto library by calling
+ /// OpenSSLInitializer::uninitialize().
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_Crypto_INCLUDED
diff --git a/include/Poco/Poco/Crypto/CryptoException.h b/include/Poco/Poco/Crypto/CryptoException.h
new file mode 100644
index 00000000..8bd5b011
--- /dev/null
+++ b/include/Poco/Poco/Crypto/CryptoException.h
@@ -0,0 +1,56 @@
+//
+// CryptoException.h
+//
+//
+// Library: Crypto
+// Package: Crypto
+// Module: CryptoException
+//
+// Definition of the CryptoException class.
+//
+// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_CryptoException_INCLUDED
+#define Crypto_CryptoException_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Exception.h"
+
+
+namespace Poco {
+namespace Crypto {
+
+
+POCO_DECLARE_EXCEPTION(Crypto_API, CryptoException, Poco::Exception)
+
+
+class Crypto_API OpenSSLException : public CryptoException
+{
+public:
+ OpenSSLException(int code = 0);
+ OpenSSLException(const std::string& msg, int code = 0);
+ OpenSSLException(const std::string& msg, const std::string& arg, int code = 0);
+ OpenSSLException(const std::string& msg, const Poco::Exception& exc, int code = 0);
+ OpenSSLException(const OpenSSLException& exc);
+ ~OpenSSLException() noexcept;
+ OpenSSLException& operator = (const OpenSSLException& exc);
+ const char* name() const noexcept;
+ const char* className() const noexcept;
+ Poco::Exception* clone() const;
+ void rethrow() const;
+
+private:
+ void setExtMessage();
+};
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_CryptoException_INCLUDED
diff --git a/include/Poco/Poco/Crypto/EVPPKey.h b/include/Poco/Poco/Crypto/EVPPKey.h
new file mode 100644
index 00000000..7cf44d86
--- /dev/null
+++ b/include/Poco/Poco/Crypto/EVPPKey.h
@@ -0,0 +1,359 @@
+//
+// EVPPKey.h
+//
+//
+// Library: Crypto
+// Package: CryptoCore
+// Module: EVPPKey
+//
+// Definition of the EVPPKey class.
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_EVPPKeyImpl_INCLUDED
+#define Crypto_EVPPKeyImpl_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Crypto/CryptoException.h"
+#include "Poco/StreamCopier.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class ECKey;
+class RSAKey;
+
+
+class Crypto_API EVPPKey
+ /// Utility class for conversion of native keys to EVP.
+ /// Currently, only RSA and EC keys are supported.
+{
+public:
+ explicit EVPPKey(const std::string& ecCurveName);
+ /// Constructs EVPPKey from ECC curve name.
+ ///
+ /// Only EC keys can be wrapped by an EVPPKey
+ /// created using this constructor.
+
+ explicit EVPPKey(const char* ecCurveName);
+ /// Constructs EVPPKey from ECC curve name.
+ ///
+ /// Only EC keys can be wrapped by an EVPPKey
+ /// created using this constructor.
+
+ explicit EVPPKey(EVP_PKEY* pEVPPKey);
+ /// Constructs EVPPKey from EVP_PKEY pointer.
+ /// The content behind the supplied pointer is internally duplicated.
+
+ template
+ explicit EVPPKey(K* pKey): _pEVPPKey(EVP_PKEY_new())
+ /// Constructs EVPPKey from a "native" OpenSSL (RSA or EC_KEY),
+ /// or a Poco wrapper (RSAKey, ECKey) key pointer.
+ {
+ if (!_pEVPPKey) throw OpenSSLException();
+ setKey(pKey);
+ }
+
+ EVPPKey(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase = "");
+ /// Creates the EVPPKey, by reading public and private key from the given files and
+ /// using the given passphrase for the private key. Can only by used for signing if
+ /// a private key is available.
+
+ EVPPKey(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase = "");
+ /// Creates the EVPPKey. Can only by used for signing if pPrivKey
+ /// is not null. If a private key file is specified, you don't need to
+ /// specify a public key file. OpenSSL will auto-create it from the private key.
+
+ EVPPKey(const EVPPKey& other);
+ /// Copy constructor.
+
+ EVPPKey(EVPPKey&& other) noexcept;
+ /// Move constructor.
+
+ EVPPKey& operator = (const EVPPKey& other);
+ /// Assignment operator.
+
+ EVPPKey& operator = (EVPPKey&& other) noexcept;
+ /// Assignment move operator.
+
+ ~EVPPKey();
+ /// Destroys the EVPPKey.
+
+ bool operator == (const EVPPKey& other) const;
+ /// Comparison operator.
+ /// Returns true if public key components and parameters
+ /// of the other key are equal to this key.
+ ///
+ /// Works as expected when one key contains only public key,
+ /// while the other one contains private (thus also public) key.
+
+ bool operator != (const EVPPKey& other) const;
+ /// Comparison operator.
+ /// Returns true if public key components and parameters
+ /// of the other key are different from this key.
+ ///
+ /// Works as expected when one key contains only public key,
+ /// while the other one contains private (thus also public) key.
+
+ void save(const std::string& publicKeyFile, const std::string& privateKeyFile = "", const std::string& privateKeyPassphrase = "") const;
+ /// Exports the public and/or private keys to the given files.
+ ///
+ /// If an empty filename is specified, the corresponding key
+ /// is not exported.
+
+ void save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStream = 0, const std::string& privateKeyPassphrase = "") const;
+ /// Exports the public and/or private key to the given streams.
+ ///
+ /// If a null pointer is passed for a stream, the corresponding
+ /// key is not exported.
+
+ int type() const;
+ /// Retuns the EVPPKey type NID.
+
+ bool isSupported(int type) const;
+ /// Returns true if OpenSSL type is supported
+
+ operator const EVP_PKEY*() const;
+ /// Returns const pointer to the OpenSSL EVP_PKEY structure.
+
+ operator EVP_PKEY*();
+ /// Returns pointer to the OpenSSL EVP_PKEY structure.
+
+ static EVP_PKEY* duplicate(const EVP_PKEY* pFromKey, EVP_PKEY** pToKey);
+ /// Duplicates pFromKey into *pToKey and returns
+ // the pointer to duplicated EVP_PKEY.
+
+private:
+ EVPPKey();
+
+ static int type(const EVP_PKEY* pEVPPKey);
+ void newECKey(const char* group);
+ void duplicate(EVP_PKEY* pEVPPKey);
+
+ void setKey(ECKey* pKey);
+ void setKey(RSAKey* pKey);
+ void setKey(EC_KEY* pKey);
+ void setKey(RSA* pKey);
+ static int passCB(char* buf, int size, int, void* pass);
+
+ typedef EVP_PKEY* (*PEM_read_FILE_Key_fn)(FILE*, EVP_PKEY**, pem_password_cb*, void*);
+ typedef EVP_PKEY* (*PEM_read_BIO_Key_fn)(BIO*, EVP_PKEY**, pem_password_cb*, void*);
+ typedef void* (*EVP_PKEY_get_Key_fn)(EVP_PKEY*);
+
+ // The following load*() functions are used by both native and EVP_PKEY type key
+ // loading from BIO/FILE.
+ // When used for EVP key loading, getFunc is null (ie. native key is not extracted
+ // from the loaded EVP_PKEY).
+ template
+ static bool loadKey(K** ppKey,
+ PEM_read_FILE_Key_fn readFunc,
+ F getFunc,
+ const std::string& keyFile,
+ const std::string& pass = "")
+ {
+ poco_assert_dbg (((typeid(K*) == typeid(RSA*) || typeid(K*) == typeid(EC_KEY*)) && getFunc) ||
+ ((typeid(K*) == typeid(EVP_PKEY*)) && !getFunc));
+ poco_check_ptr (ppKey);
+ poco_assert_dbg (!*ppKey);
+
+ FILE* pFile = 0;
+ if (!keyFile.empty())
+ {
+ if (!getFunc) *ppKey = (K*)EVP_PKEY_new();
+ EVP_PKEY* pKey = getFunc ? EVP_PKEY_new() : (EVP_PKEY*)*ppKey;
+ if (pKey)
+ {
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4996) // deprecation warnings
+#endif
+ pFile = fopen(keyFile.c_str(), "r");
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+ if (pFile)
+ {
+ pem_password_cb* pCB = pass.empty() ? (pem_password_cb*)0 : &passCB;
+ void* pPassword = pass.empty() ? (void*)0 : (void*)pass.c_str();
+ if (readFunc(pFile, &pKey, pCB, pPassword))
+ {
+ fclose(pFile); pFile = 0;
+ if(getFunc)
+ {
+ *ppKey = (K*)getFunc(pKey);
+ EVP_PKEY_free(pKey);
+ }
+ else
+ {
+ poco_assert_dbg (typeid(K*) == typeid(EVP_PKEY*));
+ *ppKey = (K*)pKey;
+ }
+ if (!*ppKey) goto error;
+ return true;
+ }
+ if (getFunc) EVP_PKEY_free(pKey);
+ goto error;
+ }
+ else
+ {
+ if (getFunc) EVP_PKEY_free(pKey);
+ throw IOException("ECKeyImpl, cannot open file", keyFile);
+ }
+ }
+ else goto error;
+ }
+ return false;
+
+ error:
+ if (pFile) fclose(pFile);
+ throw OpenSSLException("EVPKey::loadKey(string)");
+ }
+
+ template
+ static bool loadKey(K** ppKey,
+ PEM_read_BIO_Key_fn readFunc,
+ F getFunc,
+ std::istream* pIstr,
+ const std::string& pass = "")
+ {
+ poco_assert_dbg (((typeid(K*) == typeid(RSA*) || typeid(K*) == typeid(EC_KEY*)) && getFunc) ||
+ ((typeid(K*) == typeid(EVP_PKEY*)) && !getFunc));
+ poco_check_ptr(ppKey);
+ poco_assert_dbg(!*ppKey);
+
+ BIO* pBIO = 0;
+ if (pIstr)
+ {
+ std::ostringstream ostr;
+ Poco::StreamCopier::copyStream(*pIstr, ostr);
+ std::string key = ostr.str();
+ pBIO = BIO_new_mem_buf(const_cast(key.data()), static_cast(key.size()));
+ if (pBIO)
+ {
+ if (!getFunc) *ppKey = (K*)EVP_PKEY_new();
+ EVP_PKEY* pKey = getFunc ? EVP_PKEY_new() : (EVP_PKEY*)*ppKey;
+ if (pKey)
+ {
+ pem_password_cb* pCB = pass.empty() ? (pem_password_cb*)0 : &passCB;
+ void* pPassword = pass.empty() ? (void*)0 : (void*)pass.c_str();
+ if (readFunc(pBIO, &pKey, pCB, pPassword))
+ {
+ BIO_free(pBIO); pBIO = 0;
+ if (getFunc)
+ {
+ *ppKey = (K*)getFunc(pKey);
+ EVP_PKEY_free(pKey);
+ }
+ else
+ {
+ poco_assert_dbg (typeid(K*) == typeid(EVP_PKEY*));
+ *ppKey = (K*)pKey;
+ }
+ if (!*ppKey) goto error;
+ return true;
+ }
+ if (getFunc) EVP_PKEY_free(pKey);
+ goto error;
+ }
+ else goto error;
+ }
+ else goto error;
+ }
+ return false;
+
+ error:
+ if (pBIO) BIO_free(pBIO);
+ throw OpenSSLException("EVPKey::loadKey(stream)");
+ }
+
+ EVP_PKEY* _pEVPPKey;
+
+ friend class ECKeyImpl;
+ friend class RSAKeyImpl;
+};
+
+
+//
+// inlines
+//
+
+
+inline bool EVPPKey::operator == (const EVPPKey& other) const
+{
+ poco_check_ptr (other._pEVPPKey);
+ poco_check_ptr (_pEVPPKey);
+ return (1 == EVP_PKEY_cmp(_pEVPPKey, other._pEVPPKey));
+}
+
+
+inline bool EVPPKey::operator != (const EVPPKey& other) const
+{
+ return !(other == *this);
+}
+
+
+inline int EVPPKey::type(const EVP_PKEY* pEVPPKey)
+{
+ if (!pEVPPKey) return NID_undef;
+
+ return EVP_PKEY_type(EVP_PKEY_id(pEVPPKey));
+}
+
+
+inline int EVPPKey::type() const
+{
+ return type(_pEVPPKey);
+}
+
+
+inline bool EVPPKey::isSupported(int type) const
+{
+ return type == EVP_PKEY_EC || type == EVP_PKEY_RSA;
+}
+
+
+inline EVPPKey::operator const EVP_PKEY*() const
+{
+ return _pEVPPKey;
+}
+
+
+inline EVPPKey::operator EVP_PKEY*()
+{
+ return _pEVPPKey;
+}
+
+
+inline void EVPPKey::setKey(EC_KEY* pKey)
+{
+ if (!EVP_PKEY_set1_EC_KEY(_pEVPPKey, pKey))
+ throw OpenSSLException();
+}
+
+
+inline void EVPPKey::setKey(RSA* pKey)
+{
+ if (!EVP_PKEY_set1_RSA(_pEVPPKey, pKey))
+ throw OpenSSLException();
+}
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_EVPPKeyImpl_INCLUDED
diff --git a/include/Poco/Poco/Crypto/KeyPair.h b/include/Poco/Poco/Crypto/KeyPair.h
new file mode 100644
index 00000000..6f14a5f8
--- /dev/null
+++ b/include/Poco/Poco/Crypto/KeyPair.h
@@ -0,0 +1,144 @@
+//
+// KeyPair.h
+//
+// Library: Crypto
+// Package: CryptoCore
+// Module: KeyPair
+//
+// Definition of the KeyPair class.
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_KeyPair_INCLUDED
+#define Crypto_KeyPair_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Crypto/KeyPairImpl.h"
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class X509Certificate;
+
+
+class Crypto_API KeyPair
+ /// This is a parent class for classes storing a key pair, consisting
+ /// of private and public key. Storage of the private key is optional.
+ ///
+ /// If a private key is available, the KeyPair can be
+ /// used for decrypting data (encrypted with the public key)
+ /// or computing secure digital signatures.
+{
+public:
+ enum Type
+ {
+ KT_RSA = KeyPairImpl::KT_RSA_IMPL,
+ KT_EC = KeyPairImpl::KT_EC_IMPL
+ };
+
+ explicit KeyPair(KeyPairImpl::Ptr pKeyPairImpl = 0);
+ /// Extracts the RSA public key from the given certificate.
+
+ KeyPair(const KeyPair& other);
+ /// Copy constructor.
+
+ KeyPair(KeyPair&& other) noexcept;
+ /// Move constructor.
+
+ KeyPair& operator = (const KeyPair& other);
+ /// Assignment.
+
+ KeyPair& operator = (KeyPair&& other) noexcept;
+ /// Move assignment.
+
+ virtual ~KeyPair();
+ /// Destroys the KeyPair.
+
+ virtual int size() const;
+ /// Returns the RSA modulus size.
+
+ virtual void save(const std::string& publicKeyPairFile,
+ const std::string& privateKeyPairFile = "",
+ const std::string& privateKeyPairPassphrase = "") const;
+ /// Exports the public and private keys to the given files.
+ ///
+ /// If an empty filename is specified, the corresponding key
+ /// is not exported.
+
+ virtual void save(std::ostream* pPublicKeyPairStream,
+ std::ostream* pPrivateKeyPairStream = 0,
+ const std::string& privateKeyPairPassphrase = "") const;
+ /// Exports the public and private key to the given streams.
+ ///
+ /// If a null pointer is passed for a stream, the corresponding
+ /// key is not exported.
+
+ KeyPairImpl::Ptr impl() const;
+ /// Returns the impl object.
+
+ const std::string& name() const;
+ /// Returns key pair name
+
+ Type type() const;
+ /// Returns key pair type
+
+private:
+ KeyPairImpl::Ptr _pImpl;
+};
+
+
+//
+// inlines
+//
+inline int KeyPair::size() const
+{
+ return _pImpl->size();
+}
+
+
+inline void KeyPair::save(const std::string& publicKeyFile,
+ const std::string& privateKeyFile,
+ const std::string& privateKeyPassphrase) const
+{
+ _pImpl->save(publicKeyFile, privateKeyFile, privateKeyPassphrase);
+}
+
+
+inline void KeyPair::save(std::ostream* pPublicKeyStream,
+ std::ostream* pPrivateKeyStream,
+ const std::string& privateKeyPassphrase) const
+{
+ _pImpl->save(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase);
+}
+
+
+inline const std::string& KeyPair::name() const
+{
+ return _pImpl->name();
+}
+
+
+inline KeyPairImpl::Ptr KeyPair::impl() const
+{
+ return _pImpl;
+}
+
+
+inline KeyPair::Type KeyPair::type() const
+{
+ return (KeyPair::Type)impl()->type();
+}
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_KeyPair_INCLUDED
diff --git a/include/Poco/Poco/Crypto/KeyPairImpl.h b/include/Poco/Poco/Crypto/KeyPairImpl.h
new file mode 100644
index 00000000..6999a46d
--- /dev/null
+++ b/include/Poco/Poco/Crypto/KeyPairImpl.h
@@ -0,0 +1,107 @@
+//
+// KeyPairImpl.h
+//
+//
+// Library: Crypto
+// Package: CryptoCore
+// Module: KeyPairImpl
+//
+// Definition of the KeyPairImpl class.
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_KeyPairImplImpl_INCLUDED
+#define Crypto_KeyPairImplImpl_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Crypto/OpenSSLInitializer.h"
+#include "Poco/RefCountedObject.h"
+#include "Poco/AutoPtr.h"
+#include
+#include
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class KeyPairImpl: public Poco::RefCountedObject
+ /// Class KeyPairImpl
+{
+public:
+ enum Type
+ {
+ KT_RSA_IMPL = 0,
+ KT_EC_IMPL
+ };
+
+ using Ptr = Poco::AutoPtr;
+ using ByteVec = std::vector;
+
+ KeyPairImpl(const std::string& name, Type type);
+ /// Create KeyPairImpl with specified type and name.
+
+ virtual ~KeyPairImpl();
+ /// Destroys the KeyPairImpl.
+
+ virtual int size() const = 0;
+ /// Returns the key size.
+
+ virtual void save(const std::string& publicKeyFile,
+ const std::string& privateKeyFile = "",
+ const std::string& privateKeyPassphrase = "") const = 0;
+ /// Exports the public and private keys to the given files.
+ ///
+ /// If an empty filename is specified, the corresponding key
+ /// is not exported.
+
+ virtual void save(std::ostream* pPublicKeyStream,
+ std::ostream* pPrivateKeyStream = 0,
+ const std::string& privateKeyPassphrase = "") const = 0;
+ /// Exports the public and private key to the given streams.
+ ///
+ /// If a null pointer is passed for a stream, the corresponding
+ /// key is not exported.
+
+ const std::string& name() const;
+ /// Returns key pair name
+
+ Type type() const;
+ /// Returns key pair type
+
+private:
+ KeyPairImpl();
+
+ std::string _name;
+ Type _type;
+ OpenSSLInitializer _openSSLInitializer;
+};
+
+
+//
+// inlines
+//
+
+
+inline const std::string& KeyPairImpl::name() const
+{
+ return _name;
+}
+
+
+inline KeyPairImpl::Type KeyPairImpl::type() const
+{
+ return _type;
+}
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_KeyPairImplImpl_INCLUDED
diff --git a/include/Poco/Poco/Crypto/OpenSSLInitializer.h b/include/Poco/Poco/Crypto/OpenSSLInitializer.h
new file mode 100644
index 00000000..42c97ae4
--- /dev/null
+++ b/include/Poco/Poco/Crypto/OpenSSLInitializer.h
@@ -0,0 +1,115 @@
+//
+// OpenSSLInitializer.h
+//
+// Library: Crypto
+// Package: CryptoCore
+// Module: OpenSSLInitializer
+//
+// Definition of the OpenSSLInitializer class.
+//
+// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_OpenSSLInitializer_INCLUDED
+#define Crypto_OpenSSLInitializer_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Mutex.h"
+#include "Poco/AtomicCounter.h"
+#include
+
+#if defined(OPENSSL_FIPS) && OPENSSL_VERSION_NUMBER < 0x010001000L
+#include
+#endif
+
+
+extern "C"
+{
+ struct CRYPTO_dynlock_value
+ {
+ Poco::FastMutex _mutex;
+ };
+}
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class Crypto_API OpenSSLInitializer
+ /// Initalizes the OpenSSL library.
+ ///
+ /// The class ensures the earliest initialization and the
+ /// latest shutdown of the OpenSSL library.
+{
+public:
+ OpenSSLInitializer();
+ /// Automatically initialize OpenSSL on startup.
+
+ ~OpenSSLInitializer();
+ /// Automatically shut down OpenSSL on exit.
+
+ static void initialize();
+ /// Initializes the OpenSSL machinery.
+
+ static void uninitialize();
+ /// Shuts down the OpenSSL machinery.
+
+ static bool isFIPSEnabled();
+ // Returns true if FIPS mode is enabled, false otherwise.
+
+ static void enableFIPSMode(bool enabled);
+ // Enable or disable FIPS mode. If FIPS is not available, this method doesn't do anything.
+
+protected:
+ enum
+ {
+ SEEDSIZE = 256
+ };
+
+ // OpenSSL multithreading support
+ static void lock(int mode, int n, const char* file, int line);
+ static unsigned long id();
+ static struct CRYPTO_dynlock_value* dynlockCreate(const char* file, int line);
+ static void dynlock(int mode, struct CRYPTO_dynlock_value* lock, const char* file, int line);
+ static void dynlockDestroy(struct CRYPTO_dynlock_value* lock, const char* file, int line);
+
+private:
+ static Poco::FastMutex* _mutexes;
+ static Poco::AtomicCounter _rc;
+};
+
+
+//
+// inlines
+//
+inline bool OpenSSLInitializer::isFIPSEnabled()
+{
+#ifdef OPENSSL_FIPS
+ return FIPS_mode() ? true : false;
+#else
+ return false;
+#endif
+}
+
+#ifdef OPENSSL_FIPS
+inline void OpenSSLInitializer::enableFIPSMode(bool enabled)
+{
+ FIPS_mode_set(enabled);
+}
+#else
+inline void OpenSSLInitializer::enableFIPSMode(bool /*enabled*/)
+{
+}
+#endif
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_OpenSSLInitializer_INCLUDED
diff --git a/include/Poco/Poco/Crypto/RSAKey.h b/include/Poco/Poco/Crypto/RSAKey.h
new file mode 100644
index 00000000..51c97432
--- /dev/null
+++ b/include/Poco/Poco/Crypto/RSAKey.h
@@ -0,0 +1,134 @@
+//
+// RSAKey.h
+//
+// Library: Crypto
+// Package: RSA
+// Module: RSAKey
+//
+// Definition of the RSAKey class.
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_RSAKey_INCLUDED
+#define Crypto_RSAKey_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Crypto/KeyPair.h"
+#include "Poco/Crypto/RSAKeyImpl.h"
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class X509Certificate;
+class PKCS12Container;
+
+
+class Crypto_API RSAKey: public KeyPair
+ /// This class stores an RSA key pair, consisting
+ /// of private and public key. Storage of the private
+ /// key is optional.
+ ///
+ /// If a private key is available, the RSAKey can be
+ /// used for decrypting data (encrypted with the public key)
+ /// or computing secure digital signatures.
+{
+public:
+ enum KeyLength
+ {
+ KL_512 = 512,
+ KL_1024 = 1024,
+ KL_2048 = 2048,
+ KL_4096 = 4096
+ };
+
+ enum Exponent
+ {
+ EXP_SMALL = 0,
+ EXP_LARGE
+ };
+
+ RSAKey(const EVPPKey& key);
+ /// Constructs ECKeyImpl by extracting the EC key.
+
+ RSAKey(const X509Certificate& cert);
+ /// Extracts the RSA public key from the given certificate.
+
+ RSAKey(const PKCS12Container& cert);
+ /// Extracts the RSA private key from the given certificate.
+
+ RSAKey(KeyLength keyLength, Exponent exp);
+ /// Creates the RSAKey. Creates a new public/private keypair using the given parameters.
+ /// Can be used to sign data and verify signatures.
+
+ RSAKey(const std::string& publicKeyFile,
+ const std::string& privateKeyFile = "",
+ const std::string& privateKeyPassphrase = "");
+ /// Creates the RSAKey, by reading public and private key from the given files and
+ /// using the given passphrase for the private key.
+ ///
+ /// Cannot be used for signing or decryption unless a private key is available.
+ ///
+ /// If a private key is specified, you don't need to specify a public key file.
+ /// OpenSSL will auto-create the public key from the private key.
+
+ RSAKey(std::istream* pPublicKeyStream,
+ std::istream* pPrivateKeyStream = 0,
+ const std::string& privateKeyPassphrase = "");
+ /// Creates the RSAKey, by reading public and private key from the given streams and
+ /// using the given passphrase for the private key.
+ ///
+ /// Cannot be used for signing or decryption unless a private key is available.
+ ///
+ /// If a private key is specified, you don't need to specify a public key file.
+ /// OpenSSL will auto-create the public key from the private key.
+
+ RSAKey(const RSAKey& other);
+ /// Copy constructor.
+
+ RSAKey(RSAKey&& other) noexcept;
+ /// Move constructor.
+
+ ~RSAKey();
+ /// Destroys the RSAKey.
+
+ RSAKey& operator = (const RSAKey& other);
+ /// Assignment.
+
+ RSAKey& operator = (RSAKey&& other) noexcept;
+ /// Move assignment.
+
+ RSAKeyImpl::ByteVec modulus() const;
+ /// Returns the RSA modulus.
+
+ RSAKeyImpl::ByteVec encryptionExponent() const;
+ /// Returns the RSA encryption exponent.
+
+ RSAKeyImpl::ByteVec decryptionExponent() const;
+ /// Returns the RSA decryption exponent.
+
+ RSAKeyImpl::Ptr impl() const;
+ /// Returns the impl object.
+};
+
+
+//
+// inlines
+//
+inline RSAKeyImpl::Ptr RSAKey::impl() const
+{
+ return KeyPair::impl().cast();
+}
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_RSAKey_INCLUDED
\ No newline at end of file
diff --git a/include/Poco/Poco/Crypto/RSAKeyImpl.h b/include/Poco/Poco/Crypto/RSAKeyImpl.h
new file mode 100644
index 00000000..f89c3bf2
--- /dev/null
+++ b/include/Poco/Poco/Crypto/RSAKeyImpl.h
@@ -0,0 +1,141 @@
+//
+// RSAKeyImpl.h
+//
+// Library: Crypto
+// Package: RSA
+// Module: RSAKeyImpl
+//
+// Definition of the RSAKeyImpl class.
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_RSAKeyImplImpl_INCLUDED
+#define Crypto_RSAKeyImplImpl_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Crypto/EVPPKey.h"
+#include "Poco/Crypto/KeyPairImpl.h"
+#include "Poco/Crypto/OpenSSLInitializer.h"
+#include "Poco/RefCountedObject.h"
+#include "Poco/AutoPtr.h"
+#include
+#include
+#include
+
+
+struct bignum_st;
+struct rsa_st;
+typedef struct bignum_st BIGNUM;
+typedef struct rsa_st RSA;
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class X509Certificate;
+class PKCS12Container;
+
+
+class RSAKeyImpl: public KeyPairImpl
+ /// class RSAKeyImpl
+{
+public:
+ using Ptr = Poco::AutoPtr;
+ using ByteVec = std::vector;
+
+ RSAKeyImpl(const EVPPKey& key);
+ /// Constructs ECKeyImpl by extracting the EC key.
+
+ RSAKeyImpl(const X509Certificate& cert);
+ /// Extracts the RSA public key from the given certificate.
+
+ RSAKeyImpl(const PKCS12Container& cert);
+ /// Extracts the EC private key from the given certificate.
+
+ RSAKeyImpl(int keyLength, unsigned long exponent);
+ /// Creates the RSAKey. Creates a new public/private keypair using the given parameters.
+ /// Can be used to sign data and verify signatures.
+
+ RSAKeyImpl(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase);
+ /// Creates the RSAKey, by reading public and private key from the given files and
+ /// using the given passphrase for the private key. Can only by used for signing if
+ /// a private key is available.
+
+ RSAKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase);
+ /// Creates the RSAKey. Can only by used for signing if pPrivKey
+ /// is not null. If a private key file is specified, you don't need to
+ /// specify a public key file. OpenSSL will auto-create it from the private key.
+
+ ~RSAKeyImpl();
+ /// Destroys the RSAKeyImpl.
+
+ RSA* getRSA();
+ /// Returns the OpenSSL RSA object.
+
+ const RSA* getRSA() const;
+ /// Returns the OpenSSL RSA object.
+
+ int size() const;
+ /// Returns the RSA modulus size.
+
+ ByteVec modulus() const;
+ /// Returns the RSA modulus.
+
+ ByteVec encryptionExponent() const;
+ /// Returns the RSA encryption exponent.
+
+ ByteVec decryptionExponent() const;
+ /// Returns the RSA decryption exponent.
+
+ void save(const std::string& publicKeyFile,
+ const std::string& privateKeyFile = "",
+ const std::string& privateKeyPassphrase = "") const;
+ /// Exports the public and private keys to the given files.
+ ///
+ /// If an empty filename is specified, the corresponding key
+ /// is not exported.
+
+ void save(std::ostream* pPublicKeyStream,
+ std::ostream* pPrivateKeyStream = 0,
+ const std::string& privateKeyPassphrase = "") const;
+ /// Exports the public and private key to the given streams.
+ ///
+ /// If a null pointer is passed for a stream, the corresponding
+ /// key is not exported.
+
+private:
+ RSAKeyImpl();
+
+ void freeRSA();
+ static ByteVec convertToByteVec(const BIGNUM* bn);
+
+ RSA* _pRSA;
+};
+
+
+//
+// inlines
+//
+inline RSA* RSAKeyImpl::getRSA()
+{
+ return _pRSA;
+}
+
+
+inline const RSA* RSAKeyImpl::getRSA() const
+{
+ return _pRSA;
+}
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_RSAKeyImplImpl_INCLUDED
\ No newline at end of file
diff --git a/include/Poco/Poco/Crypto/X509Certificate.h b/include/Poco/Poco/Crypto/X509Certificate.h
new file mode 100644
index 00000000..a3ea8e16
--- /dev/null
+++ b/include/Poco/Poco/Crypto/X509Certificate.h
@@ -0,0 +1,257 @@
+//
+// X509Certificate.h
+//
+// Library: Crypto
+// Package: Certificate
+// Module: X509Certificate
+//
+// Definition of the X509Certificate class.
+//
+// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Crypto_X509Certificate_INCLUDED
+#define Crypto_X509Certificate_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Crypto/OpenSSLInitializer.h"
+#include "Poco/DigestEngine.h"
+#include "Poco/DateTime.h"
+#include "Poco/SharedPtr.h"
+#include
+#include
+#include
+#include
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class Crypto_API X509Certificate
+ /// This class represents a X509 Certificate.
+{
+public:
+ using List = std::vector;
+
+ enum NID
+ /// Name identifier for extracting information from
+ /// a certificate subject's or issuer's distinguished name.
+ {
+ NID_COMMON_NAME = 13,
+ NID_COUNTRY = 14,
+ NID_LOCALITY_NAME = 15,
+ NID_STATE_OR_PROVINCE = 16,
+ NID_ORGANIZATION_NAME = 17,
+ NID_ORGANIZATION_UNIT_NAME = 18,
+ NID_PKCS9_EMAIL_ADDRESS = 48,
+ NID_SERIAL_NUMBER = 105
+ };
+
+ explicit X509Certificate(std::istream& istr);
+ /// Creates the X509Certificate object by reading
+ /// a certificate in PEM format from a stream.
+
+ explicit X509Certificate(const std::string& path);
+ /// Creates the X509Certificate object by reading
+ /// a certificate in PEM format from a file.
+
+ explicit X509Certificate(X509* pCert);
+ /// Creates the X509Certificate from an existing
+ /// OpenSSL certificate. Ownership is taken of
+ /// the certificate.
+
+ X509Certificate(X509* pCert, bool shared);
+ /// Creates the X509Certificate from an existing
+ /// OpenSSL certificate. Ownership is taken of
+ /// the certificate. If shared is true, the
+ /// certificate's reference count is incremented.
+
+ X509Certificate(const X509Certificate& cert);
+ /// Creates the certificate by copying another one.
+
+ X509Certificate(X509Certificate&& cert) noexcept;
+ /// Creates the certificate by moving another one.
+
+ X509Certificate& operator = (const X509Certificate& cert);
+ /// Assigns a certificate.
+
+ X509Certificate& operator = (X509Certificate&& cert) noexcept;
+ /// Move assignment.
+
+ void swap(X509Certificate& cert);
+ /// Exchanges the certificate with another one.
+
+ ~X509Certificate();
+ /// Destroys the X509Certificate.
+
+ long version() const;
+ /// Returns the version of the certificate.
+
+ const std::string& serialNumber() const;
+ /// Returns the certificate serial number as a
+ /// string in decimal encoding.
+
+ const std::string& issuerName() const;
+ /// Returns the certificate issuer's distinguished name.
+
+ std::string issuerName(NID nid) const;
+ /// Extracts the information specified by the given
+ /// NID (name identifier) from the certificate issuer's
+ /// distinguished name.
+
+ const std::string& subjectName() const;
+ /// Returns the certificate subject's distinguished name.
+
+ std::string subjectName(NID nid) const;
+ /// Extracts the information specified by the given
+ /// NID (name identifier) from the certificate subject's
+ /// distinguished name.
+
+ std::string commonName() const;
+ /// Returns the common name stored in the certificate
+ /// subject's distinguished name.
+
+ void extractNames(std::string& commonName, std::set& domainNames) const;
+ /// Extracts the common name and the alias domain names from the
+ /// certificate.
+
+ Poco::DateTime validFrom() const;
+ /// Returns the date and time the certificate is valid from.
+
+ Poco::DateTime expiresOn() const;
+ /// Returns the date and time the certificate expires.
+
+ Poco::DigestEngine::Digest fingerprint(const std::string& algorithm = "SHA1") const;
+ /// Computes and returns the fingerprint of the certificate,
+ /// using the given algorithm. The algorithm must be supported
+ /// by OpenSSL, e.g., "SHA1" or "SHA256".
+
+ void save(std::ostream& stream) const;
+ /// Writes the certificate to the given stream.
+ /// The certificate is written in PEM format.
+
+ void save(const std::string& path) const;
+ /// Writes the certificate to the file given by path.
+ /// The certificate is written in PEM format.
+
+ bool issuedBy(const X509Certificate& issuerCertificate) const;
+ /// Checks whether the certificate has been issued by
+ /// the issuer given by issuerCertificate. This can be
+ /// used to validate a certificate chain.
+ ///
+ /// Verifies if the certificate has been signed with the
+ /// issuer's private key, using the public key from the issuer
+ /// certificate.
+ ///
+ /// Returns true if verification against the issuer certificate
+ /// was successful, false otherwise.
+
+ bool equals(const X509Certificate& otherCertificate) const;
+ /// Checks whether the certificate is equal to
+ /// the other certificate, by comparing the hashes
+ /// of both certificates.
+ ///
+ /// Returns true if both certificates are identical,
+ /// otherwise false.
+
+ const X509* certificate() const;
+ /// Returns the underlying OpenSSL certificate.
+
+ X509* dup() const;
+ /// Duplicates and returns the underlying OpenSSL certificate. Note that
+ /// the caller assumes responsibility for the lifecycle of the created
+ /// certificate.
+
+ std::string signatureAlgorithm() const;
+ /// Returns the certificate signature algorithm long name.
+
+ void print(std::ostream& out) const;
+ /// Prints the certificate information to ostream.
+
+ static List readPEM(const std::string& pemFileName);
+ /// Reads and returns a list of certificates from
+ /// the specified PEM file.
+
+ static void writePEM(const std::string& pemFileName, const List& list);
+ /// Writes the list of certificates to the specified PEM file.
+
+protected:
+ void load(std::istream& stream);
+ /// Loads the certificate from the given stream. The
+ /// certificate must be in PEM format.
+
+ void load(const std::string& path);
+ /// Loads the certificate from the given file. The
+ /// certificate must be in PEM format.
+
+ void init();
+ /// Extracts issuer and subject name from the certificate.
+
+private:
+ enum
+ {
+ NAME_BUFFER_SIZE = 256
+ };
+
+ std::string _issuerName;
+ std::string _subjectName;
+ std::string _serialNumber;
+ X509* _pCert;
+ OpenSSLInitializer _openSSLInitializer;
+};
+
+
+//
+// inlines
+//
+
+
+inline long X509Certificate::version() const
+{
+ // This is defined by standards (X.509 et al) to be
+ // one less than the certificate version.
+ // So, eg. a version 3 certificate will return 2.
+ return X509_get_version(_pCert) + 1;
+}
+
+
+inline const std::string& X509Certificate::serialNumber() const
+{
+ return _serialNumber;
+}
+
+
+inline const std::string& X509Certificate::issuerName() const
+{
+ return _issuerName;
+}
+
+
+inline const std::string& X509Certificate::subjectName() const
+{
+ return _subjectName;
+}
+
+
+inline const X509* X509Certificate::certificate() const
+{
+ return _pCert;
+}
+
+
+inline X509* X509Certificate::dup() const
+{
+ return X509_dup(_pCert);
+}
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_X509Certificate_INCLUDED
diff --git a/include/Poco/Poco/DateTime.h b/include/Poco/Poco/DateTime.h
new file mode 100644
index 00000000..f0ee41b9
--- /dev/null
+++ b/include/Poco/Poco/DateTime.h
@@ -0,0 +1,443 @@
+//
+// DateTime.h
+//
+// Library: Foundation
+// Package: DateTime
+// Module: DateTime
+//
+// Definition of the DateTime class.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_DateTime_INCLUDED
+#define Foundation_DateTime_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Timestamp.h"
+#include "Poco/Timespan.h"
+
+
+struct tm;
+
+
+namespace Poco {
+
+
+class Foundation_API DateTime
+ /// This class represents an instant in time, expressed
+ /// in years, months, days, hours, minutes, seconds
+ /// and milliseconds based on the Gregorian calendar.
+ /// The class is mainly useful for conversions between
+ /// UTC, Julian day and Gregorian calendar dates.
+ ///
+ /// The date and time stored in a DateTime is always in UTC
+ /// (Coordinated Universal Time) and thus independent of the
+ /// timezone in effect on the system.
+ ///
+ /// Conversion calculations are based on algorithms
+ /// collected and described by Peter Baum at
+ /// http://vsg.cape.com/~pbaum/date/date0.htm
+ ///
+ /// Internally, this class stores a date/time in two
+ /// forms (UTC and broken down) for performance reasons. Only use
+ /// this class for conversions between date/time representations.
+ /// Use the Timestamp class for everything else.
+ ///
+ /// Notes:
+ /// * Zero is a valid year (in accordance with ISO 8601 and astronomical year numbering)
+ /// * Year zero (0) is a leap year
+ /// * Negative years (years preceding 1 BC) are not supported
+ ///
+ /// For more information, please see:
+ /// * http://en.wikipedia.org/wiki/Gregorian_Calendar
+ /// * http://en.wikipedia.org/wiki/Julian_day
+ /// * http://en.wikipedia.org/wiki/UTC
+ /// * http://en.wikipedia.org/wiki/ISO_8601
+{
+public:
+ enum Months
+ /// Symbolic names for month numbers (1 to 12).
+ {
+ JANUARY = 1,
+ FEBRUARY,
+ MARCH,
+ APRIL,
+ MAY,
+ JUNE,
+ JULY,
+ AUGUST,
+ SEPTEMBER,
+ OCTOBER,
+ NOVEMBER,
+ DECEMBER
+ };
+
+ enum DaysOfWeek
+ /// Symbolic names for week day numbers (0 to 6).
+ {
+ SUNDAY = 0,
+ MONDAY,
+ TUESDAY,
+ WEDNESDAY,
+ THURSDAY,
+ FRIDAY,
+ SATURDAY
+ };
+
+ DateTime();
+ /// Creates a DateTime for the current date and time.
+
+ DateTime(const tm& tmStruct);
+ /// Creates a DateTime from tm struct.
+
+ DateTime(const Timestamp& timestamp);
+ /// Creates a DateTime for the date and time given in
+ /// a Timestamp.
+
+ DateTime(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0);
+ /// Creates a DateTime for the given Gregorian date and time.
+ /// * year is from 0 to 9999.
+ /// * month is from 1 to 12.
+ /// * day is from 1 to 31.
+ /// * hour is from 0 to 23.
+ /// * minute is from 0 to 59.
+ /// * second is from 0 to 60.
+ /// * millisecond is from 0 to 999.
+ /// * microsecond is from 0 to 999.
+ ///
+ /// Throws an InvalidArgumentException if an argument date is out of range.
+
+ DateTime(double julianDay);
+ /// Creates a DateTime for the given Julian day.
+
+ DateTime(Timestamp::UtcTimeVal utcTime, Timestamp::TimeDiff diff);
+ /// Creates a DateTime from an UtcTimeVal and a TimeDiff.
+ ///
+ /// Mainly used internally by DateTime and friends.
+
+ DateTime(const DateTime& dateTime);
+ /// Copy constructor. Creates the DateTime from another one.
+
+ ~DateTime();
+ /// Destroys the DateTime.
+
+ DateTime& operator = (const DateTime& dateTime);
+ /// Assigns another DateTime.
+
+ DateTime& operator = (const Timestamp& timestamp);
+ /// Assigns a Timestamp.
+
+ DateTime& operator = (double julianDay);
+ /// Assigns a Julian day.
+
+ DateTime& assign(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microseconds = 0);
+ /// Assigns a Gregorian date and time.
+ /// * year is from 0 to 9999.
+ /// * month is from 1 to 12.
+ /// * day is from 1 to 31.
+ /// * hour is from 0 to 23.
+ /// * minute is from 0 to 59.
+ /// * second is from 0 to 60.
+ /// * millisecond is from 0 to 999.
+ /// * microsecond is from 0 to 999.
+ ///
+ /// Throws an InvalidArgumentException if an argument date is out of range.
+
+ void swap(DateTime& dateTime);
+ /// Swaps the DateTime with another one.
+
+ int year() const;
+ /// Returns the year.
+
+ int month() const;
+ /// Returns the month (1 to 12).
+
+ int week(int firstDayOfWeek = MONDAY) const;
+ /// Returns the week number within the year.
+ /// FirstDayOfWeek should be either SUNDAY (0) or MONDAY (1).
+ /// The returned week number will be from 0 to 53. Week number 1 is the week
+ /// containing January 4. This is in accordance to ISO 8601.
+ ///
+ /// The following example assumes that firstDayOfWeek is MONDAY. For 2005, which started
+ /// on a Saturday, week 1 will be the week starting on Monday, January 3.
+ /// January 1 and 2 will fall within week 0 (or the last week of the previous year).
+ ///
+ /// For 2007, which starts on a Monday, week 1 will be the week starting on Monday, January 1.
+ /// There will be no week 0 in 2007.
+
+ int day() const;
+ /// Returns the day within the month (1 to 31).
+
+ int dayOfWeek() const;
+ /// Returns the weekday (0 to 6, where
+ /// 0 = Sunday, 1 = Monday, ..., 6 = Saturday).
+
+ int dayOfYear() const;
+ /// Returns the number of the day in the year.
+ /// January 1 is 1, February 1 is 32, etc.
+
+ int hour() const;
+ /// Returns the hour (0 to 23).
+
+ int hourAMPM() const;
+ /// Returns the hour (0 to 12).
+
+ bool isAM() const;
+ /// Returns true if hour < 12;
+
+ bool isPM() const;
+ /// Returns true if hour >= 12.
+
+ int minute() const;
+ /// Returns the minute (0 to 59).
+
+ int second() const;
+ /// Returns the second (0 to 59).
+
+ int millisecond() const;
+ /// Returns the millisecond (0 to 999)
+
+ int microsecond() const;
+ /// Returns the microsecond (0 to 999)
+
+ double julianDay() const;
+ /// Returns the julian day for the date and time.
+
+ Timestamp timestamp() const;
+ /// Returns the date and time expressed as a Timestamp.
+
+ Timestamp::UtcTimeVal utcTime() const;
+ /// Returns the date and time expressed in UTC-based
+ /// time. UTC base time is midnight, October 15, 1582.
+ /// Resolution is 100 nanoseconds.
+
+ bool operator == (const DateTime& dateTime) const;
+ bool operator != (const DateTime& dateTime) const;
+ bool operator < (const DateTime& dateTime) const;
+ bool operator <= (const DateTime& dateTime) const;
+ bool operator > (const DateTime& dateTime) const;
+ bool operator >= (const DateTime& dateTime) const;
+
+ DateTime operator + (const Timespan& span) const;
+ DateTime operator - (const Timespan& span) const;
+ Timespan operator - (const DateTime& dateTime) const;
+ DateTime& operator += (const Timespan& span);
+ DateTime& operator -= (const Timespan& span);
+
+ tm makeTM() const;
+ /// Converts DateTime to tm struct.
+
+ void makeUTC(int tzd);
+ /// Converts a local time into UTC, by applying the given time zone differential.
+
+ void makeLocal(int tzd);
+ /// Converts a UTC time into a local time, by applying the given time zone differential.
+
+ static bool isLeapYear(int year);
+ /// Returns true if the given year is a leap year;
+ /// false otherwise.
+
+ static int daysOfMonth(int year, int month);
+ /// Returns the number of days in the given month
+ /// and year. Month is from 1 to 12.
+
+ static bool isValid(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0);
+ /// Checks if the given date and time is valid
+ /// (all arguments are within a proper range).
+ ///
+ /// Returns true if all arguments are valid, false otherwise.
+
+protected:
+ static double toJulianDay(Timestamp::UtcTimeVal utcTime);
+ /// Computes the Julian day for an UTC time.
+
+ static double toJulianDay(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0);
+ /// Computes the Julian day for a Gregorian calendar date and time.
+ /// See , section 2.3.1 for the algorithm.
+
+ static Timestamp::UtcTimeVal toUtcTime(double julianDay);
+ /// Computes the UTC time for a Julian day.
+
+ void computeGregorian(double julianDay);
+ /// Computes the Gregorian date for the given Julian day.
+ /// See , section 3.3.1 for the algorithm.
+
+ void computeDaytime();
+ /// Extracts the daytime (hours, minutes, seconds, etc.) from the stored utcTime.
+
+private:
+ void checkLimit(short& lower, short& higher, short limit);
+ void normalize();
+ ///utility functions used to correct the overflow in computeGregorian
+
+ Timestamp::UtcTimeVal _utcTime;
+ short _year;
+ short _month;
+ short _day;
+ short _hour;
+ short _minute;
+ short _second;
+ short _millisecond;
+ short _microsecond;
+};
+
+
+//
+// inlines
+//
+
+
+inline double DateTime::toJulianDay(Timestamp::UtcTimeVal utcTime)
+{
+ double utcDays = double(utcTime)/864000000000.0;
+ return utcDays + 2299160.5; // first day of Gregorian reform (Oct 15 1582)
+}
+
+
+inline Timestamp::UtcTimeVal DateTime::toUtcTime(double julianDay)
+{
+ return Timestamp::UtcTimeVal((julianDay - 2299160.5)*864000000000.0);
+}
+
+
+inline Timestamp DateTime::timestamp() const
+{
+ return Timestamp::fromUtcTime(_utcTime);
+}
+
+
+inline Timestamp::UtcTimeVal DateTime::utcTime() const
+{
+ return _utcTime;
+}
+
+
+inline int DateTime::year() const
+{
+ return _year;
+}
+
+
+inline int DateTime::month() const
+{
+ return _month;
+}
+
+
+inline int DateTime::day() const
+{
+ return _day;
+}
+
+
+inline int DateTime::hour() const
+{
+ return _hour;
+}
+
+
+inline int DateTime::hourAMPM() const
+{
+ if (_hour < 1)
+ return 12;
+ else if (_hour > 12)
+ return _hour - 12;
+ else
+ return _hour;
+}
+
+
+inline bool DateTime::isAM() const
+{
+ return _hour < 12;
+}
+
+
+inline bool DateTime::isPM() const
+{
+ return _hour >= 12;
+}
+
+
+inline int DateTime::minute() const
+{
+ return _minute;
+}
+
+
+inline int DateTime::second() const
+{
+ return _second;
+}
+
+
+inline int DateTime::millisecond() const
+{
+ return _millisecond;
+}
+
+
+inline int DateTime::microsecond() const
+{
+ return _microsecond;
+}
+
+
+inline bool DateTime::operator == (const DateTime& dateTime) const
+{
+ return _utcTime == dateTime._utcTime;
+}
+
+
+inline bool DateTime::operator != (const DateTime& dateTime) const
+{
+ return _utcTime != dateTime._utcTime;
+}
+
+
+inline bool DateTime::operator < (const DateTime& dateTime) const
+{
+ return _utcTime < dateTime._utcTime;
+}
+
+
+inline bool DateTime::operator <= (const DateTime& dateTime) const
+{
+ return _utcTime <= dateTime._utcTime;
+}
+
+
+inline bool DateTime::operator > (const DateTime& dateTime) const
+{
+ return _utcTime > dateTime._utcTime;
+}
+
+
+inline bool DateTime::operator >= (const DateTime& dateTime) const
+{
+ return _utcTime >= dateTime._utcTime;
+}
+
+
+inline bool DateTime::isLeapYear(int year)
+{
+ return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0);
+}
+
+
+inline void swap(DateTime& d1, DateTime& d2)
+{
+ d1.swap(d2);
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_DateTime_INCLUDED
diff --git a/include/Poco/Poco/DefaultStrategy.h b/include/Poco/Poco/DefaultStrategy.h
new file mode 100644
index 00000000..0291f355
--- /dev/null
+++ b/include/Poco/Poco/DefaultStrategy.h
@@ -0,0 +1,226 @@
+//
+// DefaultStrategy.h
+//
+// Library: Foundation
+// Package: Events
+// Module: DefaultStrategy
+//
+// Implementation of the DefaultStrategy template.
+//
+// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_DefaultStrategy_INCLUDED
+#define Foundation_DefaultStrategy_INCLUDED
+
+
+#include "Poco/NotificationStrategy.h"
+#include "Poco/SharedPtr.h"
+#include
+
+
+namespace Poco {
+
+
+template
+class DefaultStrategy: public NotificationStrategy
+ /// Default notification strategy.
+ ///
+ /// Internally, a std::vector<> is used to store
+ /// delegate objects. Delegates are invoked in the
+ /// order in which they have been registered.
+{
+public:
+ using DelegateHandle = TDelegate*;
+ using DelegatePtr = SharedPtr;
+ using Delegates = std::vector;
+ using Iterator = typename Delegates::iterator;
+
+public:
+ DefaultStrategy()
+ {
+ }
+
+ DefaultStrategy(const DefaultStrategy& s):
+ _delegates(s._delegates)
+ {
+ }
+
+ ~DefaultStrategy()
+ {
+ }
+
+ void notify(const void* sender, TArgs& arguments)
+ {
+ for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
+ {
+ (*it)->notify(sender, arguments);
+ }
+ }
+
+ DelegateHandle add(const TDelegate& delegate)
+ {
+ DelegatePtr pDelegate(static_cast(delegate.clone()));
+ _delegates.push_back(pDelegate);
+ return pDelegate.get();
+ }
+
+ void remove(const TDelegate& delegate)
+ {
+ for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
+ {
+ if (delegate.equals(**it))
+ {
+ (*it)->disable();
+ _delegates.erase(it);
+ return;
+ }
+ }
+ }
+
+ void remove(DelegateHandle delegateHandle)
+ {
+ for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
+ {
+ if (*it == delegateHandle)
+ {
+ (*it)->disable();
+ _delegates.erase(it);
+ return;
+ }
+ }
+ }
+
+ DefaultStrategy& operator = (const DefaultStrategy& s)
+ {
+ if (this != &s)
+ {
+ _delegates = s._delegates;
+ }
+ return *this;
+ }
+
+ void clear()
+ {
+ for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
+ {
+ (*it)->disable();
+ }
+ _delegates.clear();
+ }
+
+ bool empty() const
+ {
+ return _delegates.empty();
+ }
+
+protected:
+ Delegates _delegates;
+};
+
+
+template
+class DefaultStrategy: public NotificationStrategy
+ /// Default notification strategy.
+ ///
+ /// Internally, a std::vector<> is used to store
+ /// delegate objects. Delegates are invoked in the
+ /// order in which they have been registered.
+{
+public:
+ using DelegateHandle = TDelegate*;
+ using DelegatePtr = SharedPtr;
+ using Delegates = std::vector;
+ using Iterator = typename Delegates::iterator;
+
+public:
+ DefaultStrategy()
+ {
+ }
+
+ DefaultStrategy(const DefaultStrategy& s):
+ _delegates(s._delegates)
+ {
+ }
+
+ ~DefaultStrategy()
+ {
+ }
+
+ void notify(const void* sender)
+ {
+ for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
+ {
+ (*it)->notify(sender);
+ }
+ }
+
+ DelegateHandle add(const TDelegate& delegate)
+ {
+ DelegatePtr pDelegate(static_cast(delegate.clone()));
+ _delegates.push_back(pDelegate);
+ return pDelegate.get();
+ }
+
+ void remove(const TDelegate& delegate)
+ {
+ for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
+ {
+ if (delegate.equals(**it))
+ {
+ (*it)->disable();
+ _delegates.erase(it);
+ return;
+ }
+ }
+ }
+
+ void remove(DelegateHandle delegateHandle)
+ {
+ for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
+ {
+ if (*it == delegateHandle)
+ {
+ (*it)->disable();
+ _delegates.erase(it);
+ return;
+ }
+ }
+ }
+
+ DefaultStrategy& operator = (const DefaultStrategy& s)
+ {
+ if (this != &s)
+ {
+ _delegates = s._delegates;
+ }
+ return *this;
+ }
+
+ void clear()
+ {
+ for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it)
+ {
+ (*it)->disable();
+ }
+ _delegates.clear();
+ }
+
+ bool empty() const
+ {
+ return _delegates.empty();
+ }
+
+protected:
+ Delegates _delegates;
+};
+
+
+} // namespace Poco
+
+
+#endif // Foundation_DefaultStrategy_INCLUDED
diff --git a/include/Poco/Poco/DigestEngine.h b/include/Poco/Poco/DigestEngine.h
new file mode 100644
index 00000000..7ea34d56
--- /dev/null
+++ b/include/Poco/Poco/DigestEngine.h
@@ -0,0 +1,111 @@
+//
+// DigestEngine.h
+//
+// Library: Foundation
+// Package: Crypt
+// Module: DigestEngine
+//
+// Definition of class DigestEngine.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_DigestEngine_INCLUDED
+#define Foundation_DigestEngine_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include
+
+
+namespace Poco {
+
+
+class Foundation_API DigestEngine
+ /// This class is an abstract base class
+ /// for all classes implementing a message
+ /// digest algorithm, like MD5Engine
+ /// and SHA1Engine.
+ /// Call update() repeatedly with data to
+ /// compute the digest from. When done,
+ /// call digest() to obtain the message
+ /// digest.
+{
+public:
+ using Digest = std::vector;
+
+ DigestEngine();
+ virtual ~DigestEngine();
+
+ void update(const void* data, std::size_t length);
+ void update(char data);
+ void update(const std::string& data);
+ /// Updates the digest with the given data.
+
+ virtual std::size_t digestLength() const = 0;
+ /// Returns the length of the digest in bytes.
+
+ virtual void reset() = 0;
+ /// Resets the engine so that a new
+ /// digest can be computed.
+
+ virtual const Digest& digest() = 0;
+ /// Finishes the computation of the digest and
+ /// returns the message digest. Resets the engine
+ /// and can thus only be called once for every digest.
+ /// The returned reference is valid until the next
+ /// time digest() is called, or the engine object is destroyed.
+
+ static std::string digestToHex(const Digest& bytes);
+ /// Converts a message digest into a string of hexadecimal numbers.
+
+ static Digest digestFromHex(const std::string& digest);
+ /// Converts a string created by digestToHex back to its Digest presentation
+
+ static bool constantTimeEquals(const Digest& d1, const Digest& d2);
+ /// Compares two Digest values using a constant-time comparison
+ /// algorithm. This can be used to prevent timing attacks
+ /// (as discussed in ).
+
+protected:
+ virtual void updateImpl(const void* data, std::size_t length) = 0;
+ /// Updates the digest with the given data. Must be implemented
+ /// by subclasses.
+
+private:
+ DigestEngine(const DigestEngine&);
+ DigestEngine& operator = (const DigestEngine&);
+};
+
+
+//
+// inlines
+//
+
+
+inline void DigestEngine::update(const void* data, std::size_t length)
+{
+ updateImpl(data, length);
+}
+
+
+inline void DigestEngine::update(char data)
+{
+ updateImpl(&data, 1);
+}
+
+
+inline void DigestEngine::update(const std::string& data)
+{
+ updateImpl(data.data(), data.size());
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_DigestEngine_INCLUDED
diff --git a/include/Poco/Poco/Event.h b/include/Poco/Poco/Event.h
new file mode 100644
index 00000000..92496178
--- /dev/null
+++ b/include/Poco/Poco/Event.h
@@ -0,0 +1,133 @@
+//
+// Event.h
+//
+// Library: Foundation
+// Package: Threading
+// Module: Event
+//
+// Definition of the Event class.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Event_INCLUDED
+#define Foundation_Event_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Exception.h"
+
+
+#if defined(POCO_OS_FAMILY_WINDOWS)
+#include "Poco/Event_WIN32.h"
+#elif defined(POCO_VXWORKS)
+#include "Poco/Event_VX.h"
+#else
+#include "Poco/Event_POSIX.h"
+#endif
+
+
+namespace Poco {
+
+
+class Foundation_API Event: private EventImpl
+ /// An Event is a synchronization object that
+ /// allows one thread to signal one or more
+ /// other threads that a certain event
+ /// has happened.
+ /// Usually, one thread signals an event,
+ /// while one or more other threads wait
+ /// for an event to become signalled.
+{
+public:
+ enum EventType
+ {
+ EVENT_MANUALRESET, /// Manual reset event
+ EVENT_AUTORESET /// Auto-reset event
+ };
+
+ explicit Event(EventType type = EVENT_AUTORESET);
+ /// Creates the event. If type is EVENT_AUTORESET,
+ /// the event is automatically reset after
+ /// a wait() successfully returns.
+
+ //@ deprecated
+ explicit Event(bool autoReset);
+ /// Please use Event::Event(EventType) instead.
+
+ ~Event();
+ /// Destroys the event.
+
+ void set();
+ /// Signals the event. If autoReset is true,
+ /// only one thread waiting for the event
+ /// can resume execution.
+ /// If autoReset is false, all waiting threads
+ /// can resume execution.
+
+ void wait();
+ /// Waits for the event to become signalled.
+
+ void wait(long milliseconds);
+ /// Waits for the event to become signalled.
+ /// Throws a TimeoutException if the event
+ /// does not become signalled within the specified
+ /// time interval.
+
+ bool tryWait(long milliseconds);
+ /// Waits for the event to become signalled.
+ /// Returns true if the event
+ /// became signalled within the specified
+ /// time interval, false otherwise.
+
+ void reset();
+ /// Resets the event to unsignalled state.
+
+private:
+ Event(const Event&);
+ Event& operator = (const Event&);
+};
+
+
+//
+// inlines
+//
+inline void Event::set()
+{
+ setImpl();
+}
+
+
+inline void Event::wait()
+{
+ waitImpl();
+}
+
+
+inline void Event::wait(long milliseconds)
+{
+ if (!waitImpl(milliseconds))
+ throw TimeoutException();
+}
+
+
+inline bool Event::tryWait(long milliseconds)
+{
+ return waitImpl(milliseconds);
+}
+
+
+inline void Event::reset()
+{
+ resetImpl();
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_Event_INCLUDED
diff --git a/include/Poco/Poco/Event_WIN32.h b/include/Poco/Poco/Event_WIN32.h
new file mode 100644
index 00000000..07fdb098
--- /dev/null
+++ b/include/Poco/Poco/Event_WIN32.h
@@ -0,0 +1,68 @@
+//
+// Event_WIN32.h
+//
+// Library: Foundation
+// Package: Threading
+// Module: Event
+//
+// Definition of the EventImpl class for WIN32.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Event_WIN32_INCLUDED
+#define Foundation_Event_WIN32_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Exception.h"
+#include "Poco/UnWindows.h"
+
+
+namespace Poco {
+
+
+class Foundation_API EventImpl
+{
+protected:
+ EventImpl(bool autoReset);
+ ~EventImpl();
+ void setImpl();
+ void waitImpl();
+ bool waitImpl(long milliseconds);
+ void resetImpl();
+
+private:
+ HANDLE _event;
+};
+
+
+//
+// inlines
+//
+inline void EventImpl::setImpl()
+{
+ if (!SetEvent(_event))
+ {
+ throw SystemException("cannot signal event");
+ }
+}
+
+
+inline void EventImpl::resetImpl()
+{
+ if (!ResetEvent(_event))
+ {
+ throw SystemException("cannot reset event");
+ }
+}
+
+
+} // namespace Poco
+
+
+#endif // Foundation_Event_WIN32_INCLUDED
diff --git a/include/Poco/Poco/Exception.h b/include/Poco/Poco/Exception.h
new file mode 100644
index 00000000..c2d9c8db
--- /dev/null
+++ b/include/Poco/Poco/Exception.h
@@ -0,0 +1,261 @@
+//
+// Exception.h
+//
+// Library: Foundation
+// Package: Core
+// Module: Exception
+//
+// Definition of various Poco exception classes.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Exception_INCLUDED
+#define Foundation_Exception_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include
+
+
+namespace Poco {
+
+
+class Foundation_API Exception: public std::exception
+ /// This is the base class for all exceptions defined
+ /// in the Poco class library.
+{
+public:
+ Exception(const std::string& msg, int code = 0);
+ /// Creates an exception.
+
+ Exception(const std::string& msg, const std::string& arg, int code = 0);
+ /// Creates an exception.
+
+ Exception(const std::string& msg, const Exception& nested, int code = 0);
+ /// Creates an exception and stores a clone
+ /// of the nested exception.
+
+ Exception(const Exception& exc);
+ /// Copy constructor.
+
+ ~Exception() noexcept;
+ /// Destroys the exception and deletes the nested exception.
+
+ Exception& operator = (const Exception& exc);
+ /// Assignment operator.
+
+ virtual const char* name() const noexcept;
+ /// Returns a static string describing the exception.
+
+ virtual const char* className() const noexcept;
+ /// Returns the name of the exception class.
+
+ virtual const char* what() const noexcept;
+ /// Returns a static string describing the exception.
+ ///
+ /// Same as name(), but for compatibility with std::exception.
+
+ const Exception* nested() const;
+ /// Returns a pointer to the nested exception, or
+ /// null if no nested exception exists.
+
+ const std::string& message() const;
+ /// Returns the message text.
+
+ int code() const;
+ /// Returns the exception code if defined.
+
+ std::string displayText() const;
+ /// Returns a string consisting of the
+ /// message name and the message text.
+
+ virtual Exception* clone() const;
+ /// Creates an exact copy of the exception.
+ ///
+ /// The copy can later be thrown again by
+ /// invoking rethrow() on it.
+
+ virtual void rethrow() const;
+ /// (Re)Throws the exception.
+ ///
+ /// This is useful for temporarily storing a
+ /// copy of an exception (see clone()), then
+ /// throwing it again.
+
+protected:
+ Exception(int code = 0);
+ /// Standard constructor.
+
+ void message(const std::string& msg);
+ /// Sets the message for the exception.
+
+ void extendedMessage(const std::string& arg);
+ /// Sets the extended message for the exception.
+
+private:
+ std::string _msg;
+ Exception* _pNested;
+ int _code;
+};
+
+
+//
+// inlines
+//
+inline const Exception* Exception::nested() const
+{
+ return _pNested;
+}
+
+
+inline const std::string& Exception::message() const
+{
+ return _msg;
+}
+
+
+inline void Exception::message(const std::string& msg)
+{
+ _msg = msg;
+}
+
+
+inline int Exception::code() const
+{
+ return _code;
+}
+
+
+//
+// Macros for quickly declaring and implementing exception classes.
+// Unfortunately, we cannot use a template here because character
+// pointers (which we need for specifying the exception name)
+// are not allowed as template arguments.
+//
+#define POCO_DECLARE_EXCEPTION_CODE(API, CLS, BASE, CODE) \
+ class API CLS: public BASE \
+ { \
+ public: \
+ CLS(int code = CODE); \
+ CLS(const std::string& msg, int code = CODE); \
+ CLS(const std::string& msg, const std::string& arg, int code = CODE); \
+ CLS(const std::string& msg, const Poco::Exception& exc, int code = CODE); \
+ CLS(const CLS& exc); \
+ ~CLS() noexcept; \
+ CLS& operator = (const CLS& exc); \
+ const char* name() const noexcept; \
+ const char* className() const noexcept; \
+ Poco::Exception* clone() const; \
+ void rethrow() const; \
+ };
+
+#define POCO_DECLARE_EXCEPTION(API, CLS, BASE) \
+ POCO_DECLARE_EXCEPTION_CODE(API, CLS, BASE, 0)
+
+#define POCO_IMPLEMENT_EXCEPTION(CLS, BASE, NAME) \
+ CLS::CLS(int code): BASE(code) \
+ { \
+ } \
+ CLS::CLS(const std::string& msg, int code): BASE(msg, code) \
+ { \
+ } \
+ CLS::CLS(const std::string& msg, const std::string& arg, int code): BASE(msg, arg, code) \
+ { \
+ } \
+ CLS::CLS(const std::string& msg, const Poco::Exception& exc, int code): BASE(msg, exc, code) \
+ { \
+ } \
+ CLS::CLS(const CLS& exc): BASE(exc) \
+ { \
+ } \
+ CLS::~CLS() noexcept \
+ { \
+ } \
+ CLS& CLS::operator = (const CLS& exc) \
+ { \
+ BASE::operator = (exc); \
+ return *this; \
+ } \
+ const char* CLS::name() const noexcept \
+ { \
+ return NAME; \
+ } \
+ const char* CLS::className() const noexcept \
+ { \
+ return typeid(*this).name(); \
+ } \
+ Poco::Exception* CLS::clone() const \
+ { \
+ return new CLS(*this); \
+ } \
+ void CLS::rethrow() const \
+ { \
+ throw *this; \
+ }
+
+
+//
+// Standard exception classes
+//
+POCO_DECLARE_EXCEPTION(Foundation_API, LogicException, Exception)
+POCO_DECLARE_EXCEPTION(Foundation_API, AssertionViolationException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, NullPointerException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, NullValueException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, BugcheckException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, InvalidArgumentException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, NotImplementedException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, RangeException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, IllegalStateException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, InvalidAccessException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, SignalException, LogicException)
+POCO_DECLARE_EXCEPTION(Foundation_API, UnhandledException, LogicException)
+
+POCO_DECLARE_EXCEPTION(Foundation_API, RuntimeException, Exception)
+POCO_DECLARE_EXCEPTION(Foundation_API, NotFoundException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, ExistsException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, TimeoutException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, SystemException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, RegularExpressionException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, LibraryLoadException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, LibraryAlreadyLoadedException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, NoThreadAvailableException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, PropertyNotSupportedException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, PoolOverflowException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, NoPermissionException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, OutOfMemoryException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, DataException, RuntimeException)
+
+POCO_DECLARE_EXCEPTION(Foundation_API, DataFormatException, DataException)
+POCO_DECLARE_EXCEPTION(Foundation_API, SyntaxException, DataException)
+POCO_DECLARE_EXCEPTION(Foundation_API, CircularReferenceException, DataException)
+POCO_DECLARE_EXCEPTION(Foundation_API, PathSyntaxException, SyntaxException)
+POCO_DECLARE_EXCEPTION(Foundation_API, IOException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, ProtocolException, IOException)
+POCO_DECLARE_EXCEPTION(Foundation_API, FileException, IOException)
+POCO_DECLARE_EXCEPTION(Foundation_API, FileExistsException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, FileNotFoundException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, PathNotFoundException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, FileReadOnlyException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, FileAccessDeniedException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, CreateFileException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, OpenFileException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, WriteFileException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, ReadFileException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, DirectoryNotEmptyException, FileException)
+POCO_DECLARE_EXCEPTION(Foundation_API, UnknownURISchemeException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, TooManyURIRedirectsException, RuntimeException)
+POCO_DECLARE_EXCEPTION(Foundation_API, URISyntaxException, SyntaxException)
+
+POCO_DECLARE_EXCEPTION(Foundation_API, ApplicationException, Exception)
+POCO_DECLARE_EXCEPTION(Foundation_API, BadCastException, RuntimeException)
+
+
+} // namespace Poco
+
+
+#endif // Foundation_Exception_INCLUDED
diff --git a/include/Poco/Poco/FIFOBuffer.h b/include/Poco/Poco/FIFOBuffer.h
new file mode 100644
index 00000000..7fc85ca7
--- /dev/null
+++ b/include/Poco/Poco/FIFOBuffer.h
@@ -0,0 +1,556 @@
+//
+// FIFOBuffer.h
+//
+// Library: Foundation
+// Package: Core
+// Module: FIFOBuffer
+//
+// Definition of the FIFOBuffer class.
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_FIFOBuffer_INCLUDED
+#define Foundation_FIFOBuffer_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Exception.h"
+#include "Poco/Buffer.h"
+#include "Poco/BasicEvent.h"
+#include "Poco/Mutex.h"
+#include "Poco/Format.h"
+
+
+namespace Poco {
+
+
+template
+class BasicFIFOBuffer
+ /// A simple buffer class with support for re-entrant,
+ /// FIFO-style read/write operations, as well as (optional)
+ /// empty/non-empty/full (i.e. writable/readable) transition
+ /// notifications. Buffer can be flagged with end-of-file and
+ /// error flags, which renders it un-readable/writable.
+ ///
+ /// Critical portions of code are protected by a recursive mutex.
+ /// However, to achieve thread-safety in cases where multiple
+ /// member function calls are involved and have to be atomic,
+ /// the mutex must be locked externally.
+ ///
+ /// Buffer size, as well as amount of unread data and
+ /// available space introspections are supported as well.
+ ///
+ /// This class is useful anywhere where a FIFO functionality
+ /// is needed.
+{
+public:
+ typedef T Type;
+
+ mutable Poco::BasicEvent writable;
+ /// Event indicating "writability" of the buffer,
+ /// triggered as follows:
+ ///
+ /// * when buffer transitions from non-full to full,
+ /// Writable event observers are notified, with
+ /// false value as the argument
+ ///
+ /// * when buffer transitions from full to non-full,
+ /// Writable event observers are notified, with
+ /// true value as the argument
+
+ mutable Poco::BasicEvent readable;
+ /// Event indicating "readability" of the buffer,
+ /// triggered as follows:
+ ///
+ /// * when buffer transitions from non-empty to empty,
+ /// Readable event observers are notified, with false
+ /// value as the argument
+ ///
+ /// * when FIFOBuffer transitions from empty to non-empty,
+ /// Readable event observers are notified, with true value
+ /// as the argument
+
+ BasicFIFOBuffer(std::size_t size, bool notify = false):
+ _buffer(size),
+ _begin(0),
+ _used(0),
+ _notify(notify),
+ _eof(false),
+ _error(false)
+ /// Creates the FIFOBuffer.
+ {
+ }
+
+ BasicFIFOBuffer(T* pBuffer, std::size_t size, bool notify = false):
+ _buffer(pBuffer, size),
+ _begin(0),
+ _used(0),
+ _notify(notify),
+ _eof(false),
+ _error(false)
+ /// Creates the FIFOBuffer.
+ {
+ }
+
+ BasicFIFOBuffer(const T* pBuffer, std::size_t size, bool notify = false):
+ _buffer(pBuffer, size),
+ _begin(0),
+ _used(size),
+ _notify(notify),
+ _eof(false),
+ _error(false)
+ /// Creates the FIFOBuffer.
+ {
+ }
+
+ ~BasicFIFOBuffer()
+ /// Destroys the FIFOBuffer.
+ {
+ }
+
+ void resize(std::size_t newSize, bool preserveContent = true)
+ /// Resizes the buffer. If preserveContent is true,
+ /// the content of the old buffer is preserved.
+ /// New size can be larger or smaller than
+ /// the current size, but it must not be 0.
+ /// Additionally, if the new length is smaller
+ /// than currently used length and preserveContent
+ /// is true, InvalidAccessException is thrown.
+ {
+ Mutex::ScopedLock lock(_mutex);
+
+ if (preserveContent && (newSize < _used))
+ throw InvalidAccessException("Can not resize FIFO without data loss.");
+
+ std::size_t usedBefore = _used;
+ _buffer.resize(newSize, preserveContent);
+ if (!preserveContent) _used = 0;
+ if (_notify) notify(usedBefore);
+ }
+
+ std::size_t peek(T* pBuffer, std::size_t length) const
+ /// Peeks into the data currently in the FIFO
+ /// without actually extracting it.
+ /// If length is zero, the return is immediate.
+ /// If length is greater than used length,
+ /// it is substituted with the the current FIFO
+ /// used length.
+ ///
+ /// Returns the number of elements copied in the
+ /// supplied buffer.
+ {
+ if (0 == length) return 0;
+ Mutex::ScopedLock lock(_mutex);
+ if (!isReadable()) return 0;
+ if (length > _used) length = _used;
+ std::memcpy(pBuffer, _buffer.begin() + _begin, length * sizeof(T));
+ return length;
+ }
+
+ std::size_t peek(Poco::Buffer& buffer, std::size_t length = 0) const
+ /// Peeks into the data currently in the FIFO
+ /// without actually extracting it.
+ /// Resizes the supplied buffer to the size of
+ /// data written to it. If length is not
+ /// supplied by the caller or is greater than length
+ /// of currently used data, the current FIFO used
+ /// data length is substituted for it.
+ ///
+ /// Returns the number of elements copied in the
+ /// supplied buffer.
+ {
+ Mutex::ScopedLock lock(_mutex);
+ if (!isReadable()) return 0;
+ if (0 == length || length > _used) length = _used;
+ buffer.resize(length);
+ return peek(buffer.begin(), length);
+ }
+
+ std::size_t read(T* pBuffer, std::size_t length)
+ /// Copies the data currently in the FIFO
+ /// into the supplied buffer, which must be
+ /// preallocated to at least the length size
+ /// before calling this function.
+ ///
+ /// Returns the size of the copied data.
+ {
+ if (0 == length) return 0;
+ Mutex::ScopedLock lock(_mutex);
+ if (!isReadable()) return 0;
+ std::size_t usedBefore = _used;
+ std::size_t readLen = peek(pBuffer, length);
+ poco_assert (_used >= readLen);
+ _used -= readLen;
+ if (0 == _used) _begin = 0;
+ else _begin += length;
+
+ if (_notify) notify(usedBefore);
+
+ return readLen;
+ }
+
+ std::size_t read(Poco::Buffer& buffer, std::size_t length = 0)
+ /// Copies the data currently in the FIFO
+ /// into the supplied buffer.
+ /// Resizes the supplied buffer to the size of
+ /// data written to it.
+ ///
+ /// Returns the size of the copied data.
+ {
+ Mutex::ScopedLock lock(_mutex);
+ if (!isReadable()) return 0;
+ std::size_t usedBefore = _used;
+ std::size_t readLen = peek(buffer, length);
+ poco_assert (_used >= readLen);
+ _used -= readLen;
+ if (0 == _used) _begin = 0;
+ else _begin += length;
+
+ if (_notify) notify(usedBefore);
+
+ return readLen;
+ }
+
+ std::size_t write(const T* pBuffer, std::size_t length)
+ /// Writes data from supplied buffer to the FIFO buffer.
+ /// If there is no sufficient space for the whole
+ /// buffer to be written, data up to available
+ /// length is written.
+ /// The length of data to be written is determined from the
+ /// length argument. Function does nothing and returns zero
+ /// if length argument is equal to zero.
+ ///
+ /// Returns the length of data written.
+ {
+ if (0 == length) return 0;
+
+ Mutex::ScopedLock lock(_mutex);
+
+ if (!isWritable()) return 0;
+
+ if (_buffer.size() - (_begin + _used) < length)
+ {
+ std::memmove(_buffer.begin(), begin(), _used * sizeof(T));
+ _begin = 0;
+ }
+
+ std::size_t usedBefore = _used;
+ std::size_t available = _buffer.size() - _used - _begin;
+ std::size_t len = length > available ? available : length;
+ std::memcpy(begin() + _used, pBuffer, len * sizeof(T));
+ _used += len;
+ poco_assert (_used <= _buffer.size());
+ if (_notify) notify(usedBefore);
+
+ return len;
+ }
+
+ std::size_t write(const Buffer& buffer, std::size_t length = 0)
+ /// Writes data from supplied buffer to the FIFO buffer.
+ /// If there is no sufficient space for the whole
+ /// buffer to be written, data up to available
+ /// length is written.
+ /// The length of data to be written is determined from the
+ /// length argument or buffer size (when length argument is
+ /// default zero or greater than buffer size).
+ ///
+ /// Returns the length of data written.
+ {
+ if (length == 0 || length > buffer.size())
+ length = buffer.size();
+
+ return write(buffer.begin(), length);
+ }
+
+ std::size_t size() const
+ /// Returns the size of the buffer.
+ {
+ return _buffer.size();
+ }
+
+ std::size_t used() const
+ /// Returns the size of the used portion of the buffer.
+ {
+ return _used;
+ }
+
+ std::size_t available() const
+ /// Returns the size of the available portion of the buffer.
+ {
+ return size() - _used;
+ }
+
+ void drain(std::size_t length = 0)
+ /// Drains length number of elements from the buffer.
+ /// If length is zero or greater than buffer current
+ /// content length, buffer is emptied.
+ {
+ Mutex::ScopedLock lock(_mutex);
+
+ std::size_t usedBefore = _used;
+
+ if (0 == length || length >= _used)
+ {
+ _begin = 0;
+ _used = 0;
+ }
+ else
+ {
+ _begin += length;
+ _used -= length;
+ }
+
+ if (_notify) notify(usedBefore);
+ }
+
+ void copy(const T* ptr, std::size_t length)
+ /// Copies the supplied data to the buffer and adjusts
+ /// the used buffer size.
+ {
+ poco_check_ptr(ptr);
+ if (0 == length) return;
+
+ Mutex::ScopedLock lock(_mutex);
+
+ if (length > available())
+ throw Poco::InvalidAccessException("Cannot extend buffer.");
+
+ if (!isWritable())
+ throw Poco::InvalidAccessException("Buffer not writable.");
+
+ std::memcpy(begin() + _used, ptr, length * sizeof(T));
+ std::size_t usedBefore = _used;
+ _used += length;
+ if (_notify) notify(usedBefore);
+ }
+
+ void advance(std::size_t length)
+ /// Advances buffer by length elements.
+ /// Should be called AFTER the data
+ /// was copied into the buffer.
+ {
+ Mutex::ScopedLock lock(_mutex);
+
+ if (length > available())
+ throw Poco::InvalidAccessException("Cannot extend buffer.");
+
+ if (!isWritable())
+ throw Poco::InvalidAccessException("Buffer not writable.");
+
+ if (_buffer.size() - (_begin + _used) < length)
+ {
+ std::memmove(_buffer.begin(), begin(), _used * sizeof(T));
+ _begin = 0;
+ }
+
+ std::size_t usedBefore = _used;
+ _used += length;
+ if (_notify) notify(usedBefore);
+ }
+
+ T* begin()
+ /// Returns the pointer to the beginning of the buffer.
+ {
+ Mutex::ScopedLock lock(_mutex);
+ if (_begin != 0)
+ {
+ // Move the data to the start of the buffer so begin() and next()
+ // always return consistent pointers with each other and allow writing
+ // to the end of the buffer.
+ std::memmove(_buffer.begin(), _buffer.begin() + _begin, _used * sizeof(T));
+ _begin = 0;
+ }
+ return _buffer.begin();
+ }
+
+ T* next()
+ /// Returns the pointer to the next available position in the buffer.
+ {
+ Mutex::ScopedLock lock(_mutex);
+ return begin() + _used;
+ }
+
+ T& operator [] (std::size_t index)
+ /// Returns value at index position.
+ /// Throws InvalidAccessException if index is larger than
+ /// the last valid (used) buffer position.
+ {
+ Mutex::ScopedLock lock(_mutex);
+ if (index >= _used)
+ throw InvalidAccessException(format("Index out of bounds: %z (max index allowed: %z)", index, _used - 1));
+
+ return _buffer[_begin + index];
+ }
+
+ const T& operator [] (std::size_t index) const
+ /// Returns value at index position.
+ /// Throws InvalidAccessException if index is larger than
+ /// the last valid (used) buffer position.
+ {
+ Mutex::ScopedLock lock(_mutex);
+ if (index >= _used)
+ throw InvalidAccessException(format("Index out of bounds: %z (max index allowed: %z)", index, _used - 1));
+
+ return _buffer[_begin + index];
+ }
+
+ const Buffer& buffer() const
+ /// Returns const reference to the underlying buffer.
+ {
+ return _buffer;
+ }
+
+ void setError(bool error = true)
+ /// Sets the error flag on the buffer and empties it.
+ /// If notifications are enabled, they will be triggered
+ /// if appropriate.
+ ///
+ /// Setting error flag to true prevents reading and writing
+ /// to the buffer; to re-enable FIFOBuffer for reading/writing,
+ /// the error flag must be set to false.
+ {
+ if (error)
+ {
+ bool f = false;
+ Mutex::ScopedLock lock(_mutex);
+ if (error && isReadable() && _notify) readable.notify(this, f);
+ if (error && isWritable() && _notify) writable.notify(this, f);
+ _error = error;
+ _used = 0;
+ }
+ else
+ {
+ bool t = true;
+ Mutex::ScopedLock lock(_mutex);
+ _error = false;
+ if (_notify && !_eof) writable.notify(this, t);
+ }
+ }
+
+ bool isValid() const
+ /// Returns true if error flag is not set on the buffer,
+ /// otherwise returns false.
+ {
+ return !_error;
+ }
+
+ void setEOF(bool eof = true)
+ /// Sets end-of-file flag on the buffer.
+ ///
+ /// Setting EOF flag to true prevents writing to the
+ /// buffer; reading from the buffer will still be
+ /// allowed until all data present in the buffer at the
+ /// EOF set time is drained. After that, to re-enable
+ /// FIFOBuffer for reading/writing, EOF must be
+ /// set to false.
+ ///
+ /// Setting EOF flag to false clears EOF state if it
+ /// was previously set. If EOF was not set, it has no
+ /// effect.
+ {
+ Mutex::ScopedLock lock(_mutex);
+ bool flag = !eof;
+ if (_notify) writable.notify(this, flag);
+ _eof = eof;
+ }
+
+ bool hasEOF() const
+ /// Returns true if EOF flag has been set.
+ {
+ return _eof;
+ }
+
+ bool isEOF() const
+ /// Returns true if EOF flag has been set and buffer is empty.
+ {
+ return isEmpty() && _eof;
+ }
+
+ bool isEmpty() const
+ /// Returns true is buffer is empty, false otherwise.
+ {
+ return 0 == _used;
+ }
+
+ bool isFull() const
+ /// Returns true is buffer is full, false otherwise.
+ {
+ return size() == _used;
+ }
+
+ bool isReadable() const
+ /// Returns true if buffer contains data and is not
+ /// in error state.
+ {
+ return !isEmpty() && isValid();
+ }
+
+ bool isWritable() const
+ /// Returns true if buffer is not full and is not
+ /// in error state.
+ {
+ return !isFull() && isValid() && !_eof;
+ }
+
+ void setNotify(bool notify = true)
+ /// Enables/disables notifications.
+ {
+ _notify = notify;
+ }
+
+ bool getNotify() const
+ /// Returns true if notifications are enabled, false otherwise.
+ {
+ return _notify;
+ }
+
+ Mutex& mutex()
+ /// Returns reference to mutex.
+ {
+ return _mutex;
+ }
+
+private:
+ void notify(std::size_t usedBefore)
+ {
+ bool t = true, f = false;
+ if (usedBefore == 0 && _used > 0)
+ readable.notify(this, t);
+ else if (usedBefore > 0 && 0 == _used)
+ readable.notify(this, f);
+
+ if (usedBefore == _buffer.size() && _used < _buffer.size())
+ writable.notify(this, t);
+ else if (usedBefore < _buffer.size() && _used == _buffer.size())
+ writable.notify(this, f);
+ }
+
+ BasicFIFOBuffer();
+ BasicFIFOBuffer(const BasicFIFOBuffer&);
+ BasicFIFOBuffer& operator = (const BasicFIFOBuffer&);
+
+ Buffer _buffer;
+ std::size_t _begin;
+ std::size_t _used;
+ bool _notify;
+ mutable Mutex _mutex;
+ bool _eof;
+ bool _error;
+};
+
+
+//
+// We provide an instantiation for char
+//
+typedef BasicFIFOBuffer FIFOBuffer;
+
+
+} // namespace Poco
+
+
+#endif // Foundation_FIFOBuffer_INCLUDED
diff --git a/include/Poco/Poco/Format.h b/include/Poco/Poco/Format.h
new file mode 100644
index 00000000..780f4e4c
--- /dev/null
+++ b/include/Poco/Poco/Format.h
@@ -0,0 +1,180 @@
+//
+// Format.h
+//
+// Library: Foundation
+// Package: Core
+// Module: Format
+//
+// Definition of the format freestanding function.
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#ifndef Foundation_Format_INCLUDED
+#define Foundation_Format_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Any.h"
+#include
+#include
+
+
+namespace Poco {
+
+
+std::string Foundation_API format(const std::string& fmt, const Any& value);
+ /// This function implements sprintf-style formatting in a typesafe way.
+ /// Various variants of the function are available, supporting a
+ /// different number of arguments (up to six).
+ ///
+ /// The formatting is controlled by the format string in fmt.
+ /// Format strings are quite similar to those of the std::printf() function, but
+ /// there are some minor differences.
+ ///
+ /// The format string can consist of any sequence of characters; certain
+ /// characters have a special meaning. Characters without a special meaning
+ /// are copied verbatim to the result. A percent sign (%) marks the beginning
+ /// of a format specification. Format specifications have the following syntax:
+ ///
+ /// %[][][][.