1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-16 07:07:13 +02:00

Major plugin refactor and cleanup.

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

View File

@ -0,0 +1,51 @@
//
// ASCIIEncoding.h
//
// Library: Foundation
// Package: Text
// Module: ASCIIEncoding
//
// Definition of the ASCIIEncoding class.
//
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ASCIIEncoding_INCLUDED
#define Foundation_ASCIIEncoding_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/TextEncoding.h"
namespace Poco {
class Foundation_API ASCIIEncoding: public TextEncoding
/// 7-bit ASCII text encoding.
{
public:
ASCIIEncoding();
~ASCIIEncoding();
const char* canonicalName() const;
bool isA(const std::string& encodingName) const;
const CharacterMap& characterMap() const;
int convert(const unsigned char* bytes) const;
int convert(int ch, unsigned char* bytes, int length) const;
int queryConvert(const unsigned char* bytes, int length) const;
int sequenceLength(const unsigned char* bytes, int length) const;
private:
static const char* _names[];
static const CharacterMap _charMap;
};
} // namespace Poco
#endif // Foundation_ASCIIEncoding_INCLUDED

View File

@ -0,0 +1,366 @@
//
// AbstractCache.h
//
// Library: Foundation
// Package: Cache
// Module: AbstractCache
//
// Definition of the AbstractCache class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AbstractCache_INCLUDED
#define Foundation_AbstractCache_INCLUDED
#include "Poco/KeyValueArgs.h"
#include "Poco/ValidArgs.h"
#include "Poco/Mutex.h"
#include "Poco/Exception.h"
#include "Poco/FIFOEvent.h"
#include "Poco/EventArgs.h"
#include "Poco/Delegate.h"
#include "Poco/SharedPtr.h"
#include <map>
#include <set>
#include <cstddef>
namespace Poco {
template <class TKey, class TValue, class TStrategy, class TMutex = FastMutex, class TEventMutex = FastMutex>
class AbstractCache
/// An AbstractCache is the interface of all caches.
{
public:
FIFOEvent<const KeyValueArgs<TKey, TValue>, TEventMutex> Add;
FIFOEvent<const KeyValueArgs<TKey, TValue>, TEventMutex> Update;
FIFOEvent<const TKey, TEventMutex> Remove;
FIFOEvent<const TKey, TEventMutex> Get;
FIFOEvent<const EventArgs, TEventMutex> Clear;
typedef std::map<TKey, SharedPtr<TValue>> DataHolder;
typedef typename DataHolder::iterator Iterator;
typedef typename DataHolder::const_iterator ConstIterator;
typedef std::set<TKey> KeySet;
AbstractCache()
{
initialize();
}
AbstractCache(const TStrategy& strat): _strategy(strat)
{
initialize();
}
virtual ~AbstractCache()
{
try
{
uninitialize();
}
catch (...)
{
poco_unexpected();
}
}
void add(const TKey& key, const TValue& val)
/// Adds the key value pair to the cache.
/// If for the key already an entry exists, it will be overwritten.
{
typename TMutex::ScopedLock lock(_mutex);
doAdd(key, val);
}
void update(const TKey& key, const TValue& val)
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
/// If for the key already an entry exists, it will be overwritten.
/// The difference to add is that no remove or add events are thrown in this case,
/// just a simply silent update is performed
/// If the key does not exist the behavior is equal to add, ie. an add event is thrown
{
typename TMutex::ScopedLock lock(_mutex);
doUpdate(key, val);
}
void add(const TKey& key, SharedPtr<TValue > val)
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
/// If for the key already an entry exists, it will be overwritten, ie. first a remove event
/// is thrown, then a add event
{
typename TMutex::ScopedLock lock(_mutex);
doAdd(key, val);
}
void update(const TKey& key, SharedPtr<TValue > val)
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
/// If for the key already an entry exists, it will be overwritten.
/// The difference to add is that no remove or add events are thrown in this case,
/// just an Update is thrown
/// If the key does not exist the behavior is equal to add, ie. an add event is thrown
{
typename TMutex::ScopedLock lock(_mutex);
doUpdate(key, val);
}
void remove(const TKey& key)
/// Removes an entry from the cache. If the entry is not found,
/// the remove is ignored.
{
typename TMutex::ScopedLock lock(_mutex);
Iterator it = _data.find(key);
doRemove(it);
}
bool has(const TKey& key) const
/// Returns true if the cache contains a value for the key.
{
typename TMutex::ScopedLock lock(_mutex);
return doHas(key);
}
SharedPtr<TValue> get(const TKey& key)
/// Returns a SharedPtr of the value. The SharedPointer will remain valid
/// even when cache replacement removes the element.
/// If for the key no value exists, an empty SharedPtr is returned.
{
typename TMutex::ScopedLock lock(_mutex);
return doGet (key);
}
void clear()
/// Removes all elements from the cache.
{
typename TMutex::ScopedLock lock(_mutex);
doClear();
}
std::size_t size()
/// Returns the number of cached elements
{
typename TMutex::ScopedLock lock(_mutex);
doReplace();
return _data.size();
}
void forceReplace()
/// Forces cache replacement. Note that Poco's cache strategy use for efficiency reason no background thread
/// which periodically triggers cache replacement. Cache Replacement is only started when the cache is modified
/// from outside, i.e. add is called, or when a user tries to access an cache element via get.
/// In some cases, i.e. expire based caching where for a long time no access to the cache happens,
/// it might be desirable to be able to trigger cache replacement manually.
{
typename TMutex::ScopedLock lock(_mutex);
doReplace();
}
std::set<TKey> getAllKeys()
/// Returns a copy of all keys stored in the cache
{
typename TMutex::ScopedLock lock(_mutex);
doReplace();
ConstIterator it = _data.begin();
ConstIterator itEnd = _data.end();
std::set<TKey> result;
for (; it != itEnd; ++it)
result.insert(it->first);
return result;
}
protected:
mutable FIFOEvent<ValidArgs<TKey>> IsValid;
mutable FIFOEvent<KeySet> Replace;
void initialize()
/// Sets up event registration.
{
Add += Delegate<TStrategy, const KeyValueArgs<TKey, TValue>>(&_strategy, &TStrategy::onAdd);
Update += Delegate<TStrategy, const KeyValueArgs<TKey, TValue>>(&_strategy, &TStrategy::onUpdate);
Remove += Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onRemove);
Get += Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onGet);
Clear += Delegate<TStrategy, const EventArgs>(&_strategy, &TStrategy::onClear);
IsValid += Delegate<TStrategy, ValidArgs<TKey>>(&_strategy, &TStrategy::onIsValid);
Replace += Delegate<TStrategy, KeySet>(&_strategy, &TStrategy::onReplace);
}
void uninitialize()
/// Reverts event registration.
{
Add -= Delegate<TStrategy, const KeyValueArgs<TKey, TValue>>(&_strategy, &TStrategy::onAdd );
Update -= Delegate<TStrategy, const KeyValueArgs<TKey, TValue>>(&_strategy, &TStrategy::onUpdate);
Remove -= Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onRemove);
Get -= Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onGet);
Clear -= Delegate<TStrategy, const EventArgs>(&_strategy, &TStrategy::onClear);
IsValid -= Delegate<TStrategy, ValidArgs<TKey>>(&_strategy, &TStrategy::onIsValid);
Replace -= Delegate<TStrategy, KeySet>(&_strategy, &TStrategy::onReplace);
}
void doAdd(const TKey& key, const TValue& val)
/// Adds the key value pair to the cache.
/// If for the key already an entry exists, it will be overwritten.
{
Iterator it = _data.find(key);
doRemove(it);
KeyValueArgs<TKey, TValue> args(key, val);
Add.notify(this, args);
_data.insert(std::make_pair(key, SharedPtr<TValue>(new TValue(val))));
doReplace();
}
void doAdd(const TKey& key, SharedPtr<TValue>& val)
/// Adds the key value pair to the cache.
/// If for the key already an entry exists, it will be overwritten.
{
Iterator it = _data.find(key);
doRemove(it);
KeyValueArgs<TKey, TValue> args(key, *val);
Add.notify(this, args);
_data.insert(std::make_pair(key, val));
doReplace();
}
void doUpdate(const TKey& key, const TValue& val)
/// Adds the key value pair to the cache.
/// If for the key already an entry exists, it will be overwritten.
{
KeyValueArgs<TKey, TValue> args(key, val);
Iterator it = _data.find(key);
if (it == _data.end())
{
Add.notify(this, args);
_data.insert(std::make_pair(key, SharedPtr<TValue>(new TValue(val))));
}
else
{
Update.notify(this, args);
it->second = SharedPtr<TValue>(new TValue(val));
}
doReplace();
}
void doUpdate(const TKey& key, SharedPtr<TValue>& val)
/// Adds the key value pair to the cache.
/// If for the key already an entry exists, it will be overwritten.
{
KeyValueArgs<TKey, TValue> args(key, *val);
Iterator it = _data.find(key);
if (it == _data.end())
{
Add.notify(this, args);
_data.insert(std::make_pair(key, val));
}
else
{
Update.notify(this, args);
it->second = val;
}
doReplace();
}
void doRemove(Iterator it)
/// Removes an entry from the cache. If the entry is not found
/// the remove is ignored.
{
if (it != _data.end())
{
Remove.notify(this, it->first);
_data.erase(it);
}
}
bool doHas(const TKey& key) const
/// Returns true if the cache contains a value for the key
{
// ask the strategy if the key is valid
ConstIterator it = _data.find(key);
bool result = false;
if (it != _data.end())
{
ValidArgs<TKey> args(key);
IsValid.notify(this, args);
result = args.isValid();
}
return result;
}
SharedPtr<TValue> doGet(const TKey& key)
/// Returns a SharedPtr of the cache entry, returns 0 if for
/// the key no value was found
{
Iterator it = _data.find(key);
SharedPtr<TValue> result;
if (it != _data.end())
{
// inform all strategies that a read-access to an element happens
Get.notify(this, key);
// ask all strategies if the key is valid
ValidArgs<TKey> args(key);
IsValid.notify(this, args);
if (!args.isValid())
{
doRemove(it);
}
else
{
result = it->second;
}
}
return result;
}
void doClear()
{
static EventArgs _emptyArgs;
Clear.notify(this, _emptyArgs);
_data.clear();
}
void doReplace()
{
std::set<TKey> delMe;
Replace.notify(this, delMe);
// delMe contains the to be removed elements
typename std::set<TKey>::const_iterator it = delMe.begin();
typename std::set<TKey>::const_iterator endIt = delMe.end();
for (; it != endIt; ++it)
{
Iterator itH = _data.find(*it);
doRemove(itH);
}
}
TStrategy _strategy;
mutable DataHolder _data;
mutable TMutex _mutex;
private:
AbstractCache(const AbstractCache& aCache);
AbstractCache& operator = (const AbstractCache& aCache);
};
} // namespace Poco
#endif // Foundation_AbstractCache_INCLUDED

View File

@ -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 TArgs>
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<void>
/// 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

View File

@ -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 TArgs, class TStrategy, class TDelegate, class TMutex = FastMutex>
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<int> 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<TMutex> 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<TArgs> 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<TStrategy>(new TStrategy(_strategy));
params.enabled = _enabled;
}
ActiveResult<TArgs> 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<TStrategy> 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<TArgs, NotifyAsyncParams, AbstractEvent> _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 TStrategy, class TDelegate, class TMutex>
class AbstractEvent<void, TStrategy, TDelegate, TMutex>
{
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<TMutex> 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<void> 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<TStrategy>(new TStrategy(_strategy));
params.enabled = _enabled;
}
ActiveResult<void> 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<TStrategy> 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<void, NotifyAsyncParams, AbstractEvent> _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

View File

@ -0,0 +1,50 @@
//
// AbstractObserver.h
//
// Library: Foundation
// Package: Notifications
// Module: NotificationCenter
//
// Definition of the AbstractObserver class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AbstractObserver_INCLUDED
#define Foundation_AbstractObserver_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Notification.h"
namespace Poco {
class Foundation_API AbstractObserver
/// The base class for all instantiations of
/// the Observer and NObserver template classes.
{
public:
AbstractObserver();
AbstractObserver(const AbstractObserver& observer);
virtual ~AbstractObserver();
AbstractObserver& operator = (const AbstractObserver& observer);
virtual void notify(Notification* pNf) const = 0;
virtual bool equals(const AbstractObserver& observer) const = 0;
virtual bool accepts(Notification* pNf) const = 0;
virtual AbstractObserver* clone() const = 0;
virtual void disable() = 0;
};
} // namespace Poco
#endif // Foundation_AbstractObserver_INCLUDED

View File

@ -0,0 +1,63 @@
//
// AbstractPriorityDelegate.h
//
// Library: Foundation
// Package: Events
// Module: AbstractPriorityDelegate
//
// Implementation of the AbstractPriorityDelegate template.
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AbstractPriorityDelegate_INCLUDED
#define Foundation_AbstractPriorityDelegate_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/AbstractDelegate.h"
namespace Poco {
template <class TArgs>
class AbstractPriorityDelegate: public AbstractDelegate<TArgs>
/// Base class for PriorityDelegate and PriorityExpire.
///
/// Extends AbstractDelegate with a priority value.
{
public:
AbstractPriorityDelegate(int prio):
_priority(prio)
{
}
AbstractPriorityDelegate(const AbstractPriorityDelegate& del):
AbstractDelegate<TArgs>(del),
_priority(del._priority)
{
}
virtual ~AbstractPriorityDelegate()
{
}
int priority() const
{
return _priority;
}
protected:
int _priority;
};
} // namespace Poco
#endif // Foundation_AbstractPriorityDelegate_INCLUDED

View File

@ -0,0 +1,77 @@
//
// AbstractStrategy.h
//
// Library: Foundation
// Package: Cache
// Module: AbstractCache
//
// Definition of the AbstractStrategy class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AbstractStrategy_INCLUDED
#define Foundation_AbstractStrategy_INCLUDED
#include "Poco/KeyValueArgs.h"
#include "Poco/ValidArgs.h"
#include "Poco/EventArgs.h"
#include <set>
namespace Poco {
template <class TKey, class TValue>
class AbstractStrategy
/// An AbstractStrategy is the interface for all strategies.
{
public:
AbstractStrategy()
{
}
virtual ~AbstractStrategy()
{
}
virtual void onUpdate(const void* pSender, const KeyValueArgs <TKey, TValue>& args)
/// Updates an existing entry.
{
onRemove(pSender,args.key());
onAdd(pSender, args);
}
virtual void onAdd(const void* pSender, const KeyValueArgs <TKey, TValue>& key) = 0;
/// Adds the key to the strategy.
/// If for the key already an entry exists, an exception will be thrown.
virtual void onRemove(const void* pSender, const TKey& key) = 0;
/// Removes an entry from the strategy. If the entry is not found
/// the remove is ignored.
virtual void onGet(const void* pSender, const TKey& key) = 0;
/// Informs the strategy that a read-access happens to an element.
virtual void onClear(const void* pSender, const EventArgs& args) = 0;
/// Removes all elements from the cache.
virtual void onIsValid(const void* pSender, ValidArgs<TKey>& key) = 0;
/// Used to query if a key is still valid (i.e. cached).
virtual void onReplace(const void* pSender, std::set<TKey>& elemsToRemove) = 0;
/// Used by the Strategy to indicate which elements should be removed from
/// the cache. Note that onReplace does not change the current list of keys.
/// The cache object is responsible to remove the elements.
};
} // namespace Poco
#endif // Foundation_AbstractStrategy_INCLUDED

View File

@ -0,0 +1,83 @@
//
// AccessExpirationDecorator.h
//
// Library: Foundation
// Package: Cache
// Module: AccessExpirationDecorator
//
// Implementation of the AccessExpirationDecorator template.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AccessExpirationDecorator_INCLUDED
#define Foundation_AccessExpirationDecorator_INCLUDED
#include "Poco/Timestamp.h"
#include "Poco/Timespan.h"
namespace Poco {
template <typename TArgs>
class AccessExpirationDecorator
/// AccessExpirationDecorator adds an expiration method to values so that they can be used
/// with the UniqueAccessExpireCache
{
public:
AccessExpirationDecorator():
_value(),
_span()
{
}
AccessExpirationDecorator(const TArgs& p, const Poco::Timespan::TimeDiff& diffInMs):
/// Creates an element that will expire in diff milliseconds
_value(p),
_span(diffInMs*1000)
{
}
AccessExpirationDecorator(const TArgs& p, const Poco::Timespan& timeSpan):
/// Creates an element that will expire after the given timeSpan
_value(p),
_span(timeSpan)
{
}
~AccessExpirationDecorator()
{
}
const Poco::Timespan& getTimeout() const
{
return _span;
}
const TArgs& value() const
{
return _value;
}
TArgs& value()
{
return _value;
}
private:
TArgs _value;
Timespan _span;
};
} // namespace Poco
#endif // Foundation_AccessExpirationDecorator_INCLUDED

View File

@ -0,0 +1,63 @@
//
// AccessExpireCache.h
//
// Library: Foundation
// Package: Cache
// Module: AccessExpireCache
//
// Definition of the AccessExpireCache class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AccessExpireCache_INCLUDED
#define Foundation_AccessExpireCache_INCLUDED
#include "Poco/AbstractCache.h"
#include "Poco/AccessExpireStrategy.h"
namespace Poco {
template <
class TKey,
class TValue,
class TMutex = FastMutex,
class TEventMutex = FastMutex
>
class AccessExpireCache: public AbstractCache<TKey, TValue, AccessExpireStrategy<TKey, TValue>, TMutex, TEventMutex>
/// An AccessExpireCache caches entries for a fixed time period (per default 10 minutes).
/// Entries expire when they are not accessed with get() during this time period. Each access resets
/// the start time for expiration.
/// Be careful when using an AccessExpireCache. A cache is often used
/// like cache.has(x) followed by cache.get x). Note that it could happen
/// that the "has" call works, then the current execution thread gets descheduled, time passes,
/// the entry gets invalid, thus leading to an empty SharedPtr being returned
/// when "get" is invoked.
{
public:
AccessExpireCache(Timestamp::TimeDiff expire = 600000):
AbstractCache<TKey, TValue, AccessExpireStrategy<TKey, TValue>, TMutex, TEventMutex>(AccessExpireStrategy<TKey, TValue>(expire))
{
}
~AccessExpireCache()
{
}
private:
AccessExpireCache(const AccessExpireCache& aCache);
AccessExpireCache& operator = (const AccessExpireCache& aCache);
};
} // namespace Poco
#endif // Foundation_AccessExpireCache_INCLUDED

View File

@ -0,0 +1,62 @@
//
// AccessExpireLRUCache.h
//
// Library: Foundation
// Package: Cache
// Module: AccessExpireLRUCache
//
// Definition of the AccessExpireLRUCache class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AccessExpireLRUCache_INCLUDED
#define Foundation_AccessExpireLRUCache_INCLUDED
#include "Poco/AbstractCache.h"
#include "Poco/StrategyCollection.h"
#include "Poco/AccessExpireStrategy.h"
#include "Poco/LRUStrategy.h"
namespace Poco {
template <
class TKey,
class TValue,
class TMutex = FastMutex,
class TEventMutex = FastMutex
>
class AccessExpireLRUCache: public AbstractCache<TKey, TValue, StrategyCollection<TKey, TValue>, TMutex, TEventMutex>
/// An AccessExpireLRUCache combines LRU caching and time based expire caching.
/// It cache entries for a fixed time period (per default 10 minutes)
/// but also limits the size of the cache (per default: 1024).
{
public:
AccessExpireLRUCache(std::size_t cacheSize = 1024, Timestamp::TimeDiff expire = 600000):
AbstractCache<TKey, TValue, StrategyCollection<TKey, TValue>, TMutex, TEventMutex >(StrategyCollection<TKey, TValue>())
{
this->_strategy.pushBack(new LRUStrategy<TKey, TValue>(cacheSize));
this->_strategy.pushBack(new AccessExpireStrategy<TKey, TValue>(expire));
}
~AccessExpireLRUCache()
{
}
private:
AccessExpireLRUCache(const AccessExpireLRUCache& aCache);
AccessExpireLRUCache& operator = (const AccessExpireLRUCache& aCache);
};
} // namespace Poco
#endif // Foundation_AccessExpireLRUCache_INCLUDED

View File

@ -0,0 +1,74 @@
//
// AccessExpireStrategy.h
//
// Library: Foundation
// Package: Cache
// Module: AccessExpireStrategy
//
// Definition of the AccessExpireStrategy class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AccessExpireStrategy_INCLUDED
#define Foundation_AccessExpireStrategy_INCLUDED
#include "Poco/KeyValueArgs.h"
#include "Poco/ValidArgs.h"
#include "Poco/ExpireStrategy.h"
#include "Poco/Bugcheck.h"
#include "Poco/Timestamp.h"
#include "Poco/EventArgs.h"
#include <set>
#include <map>
namespace Poco {
template <
class TKey,
class TValue
>
class AccessExpireStrategy: public ExpireStrategy<TKey, TValue>
/// An AccessExpireStrategy implements time and access based expiration of cache entries
{
public:
AccessExpireStrategy(Timestamp::TimeDiff expireTimeInMilliSec): ExpireStrategy<TKey, TValue>(expireTimeInMilliSec)
/// Create an expire strategy. Note that the smallest allowed caching time is 25ms.
/// Anything lower than that is not useful with current operating systems.
{
}
~AccessExpireStrategy()
{
}
void onGet(const void*, const TKey& key)
{
// get triggers an update to the expiration time
typename ExpireStrategy<TKey, TValue>::Iterator it = this->_keys.find(key);
if (it != this->_keys.end())
{
if (!it->second->first.isElapsed(this->_expireTime)) // don't extend if already expired
{
this->_keyIndex.erase(it->second);
Timestamp now;
typename ExpireStrategy<TKey, TValue>::IndexIterator itIdx =
this->_keyIndex.insert(typename ExpireStrategy<TKey, TValue>::TimeIndex::value_type(now, key));
it->second = itIdx;
}
}
}
};
} // namespace Poco
#endif // Foundation_AccessExpireStrategy_INCLUDED

View File

@ -0,0 +1,116 @@
//
// ActiveDispatcher.h
//
// Library: Foundation
// Package: Threading
// Module: ActiveObjects
//
// Definition of the ActiveDispatcher class.
//
// Copyright (c) 2006-2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ActiveDispatcher_INCLUDED
#define Foundation_ActiveDispatcher_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Runnable.h"
#include "Poco/Thread.h"
#include "Poco/ActiveStarter.h"
#include "Poco/ActiveRunnable.h"
#include "Poco/NotificationQueue.h"
namespace Poco {
class Foundation_API ActiveDispatcher: protected Runnable
/// This class is used to implement an active object
/// with strictly serialized method execution.
///
/// An active object, which is an ordinary object
/// containing ActiveMethod members, executes all
/// active methods in their own thread.
/// This behavior does not fit the "classic"
/// definition of an active object, which serializes
/// the execution of active methods (in other words,
/// only one active method can be running at any given
/// time).
///
/// Using this class as a base class, the serializing
/// behavior for active objects can be implemented.
///
/// The following example shows how this is done:
///
/// class ActiveObject: public ActiveDispatcher
/// {
/// public:
/// ActiveObject():
/// exampleActiveMethod(this, &ActiveObject::exampleActiveMethodImpl)
/// {
/// }
///
/// ActiveMethod<std::string, std::string, ActiveObject, ActiveStarter<ActiveDispatcher>> exampleActiveMethod;
///
/// protected:
/// std::string exampleActiveMethodImpl(const std::string& arg)
/// {
/// ...
/// }
/// };
///
/// The only things different from the example in
/// ActiveMethod is that the ActiveObject in this case
/// inherits from ActiveDispatcher, and that the ActiveMethod
/// template for exampleActiveMethod has an additional parameter,
/// specifying the specialized ActiveStarter for ActiveDispatcher.
{
public:
ActiveDispatcher();
/// Creates the ActiveDispatcher.
ActiveDispatcher(Thread::Priority prio);
/// Creates the ActiveDispatcher and sets
/// the priority of its thread.
virtual ~ActiveDispatcher();
/// Destroys the ActiveDispatcher.
void start(ActiveRunnableBase::Ptr pRunnable);
/// Adds the Runnable to the dispatch queue.
void cancel();
/// Cancels all queued methods.
protected:
void run();
void stop();
private:
Thread _thread;
NotificationQueue _queue;
};
template <>
class ActiveStarter<ActiveDispatcher>
/// A specialization of ActiveStarter
/// for ActiveDispatcher.
{
public:
static void start(ActiveDispatcher* pOwner, ActiveRunnableBase::Ptr pRunnable)
{
pOwner->start(pRunnable);
}
};
} // namespace Poco
#endif // Foundation_ActiveDispatcher_INCLUDED

View File

@ -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 ResultType, class ArgType, class OwnerType, class StarterType = ActiveStarter<OwnerType>>
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<std::string, std::string, ActiveObject> exampleActiveMethod;
///
/// protected:
/// std::string exampleActiveMethodImpl(const std::string& arg)
/// {
/// ...
/// }
/// };
///
/// And following is an example that shows how to invoke an ActiveMethod.
///
/// ActiveObject myActiveObject;
/// ActiveResult<std::string> 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<ResultType> ActiveResultType;
typedef ActiveRunnable<ResultType, ArgType, OwnerType> 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<ResultType>());
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 ResultType, class OwnerType, class StarterType>
class ActiveMethod <ResultType, void, OwnerType, StarterType>
/// 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<std::string, std::string, ActiveObject> exampleActiveMethod;
///
/// protected:
/// std::string exampleActiveMethodImpl(const std::string& arg)
/// {
/// ...
/// }
/// };
///
/// And following is an example that shows how to invoke an ActiveMethod.
///
/// ActiveObject myActiveObject;
/// ActiveResult<std::string> 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<ResultType> ActiveResultType;
typedef ActiveRunnable<ResultType, void, OwnerType> 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<ResultType>());
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

View File

@ -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 <algorithm>
namespace Poco {
template <class ResultType>
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<void>: 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 RT>
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<ResultType> 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<void>
/// 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<void> 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

View File

@ -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<ActiveRunnableBase>;
};
template <class ResultType, class ArgType, class OwnerType>
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<ResultType> 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 ArgType, class OwnerType>
class ActiveRunnable<void, ArgType, OwnerType>: public ActiveRunnableBase
/// This class is used by ActiveMethod.
/// See the ActiveMethod class for more information.
{
public:
typedef void (OwnerType::*Callback)(const ArgType&);
typedef ActiveResult<void> 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 ResultType, class OwnerType>
class ActiveRunnable<ResultType, void, OwnerType>: public ActiveRunnableBase
/// This class is used by ActiveMethod.
/// See the ActiveMethod class for more information.
{
public:
typedef ResultType (OwnerType::*Callback)();
typedef ActiveResult<ResultType> 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 OwnerType>
class ActiveRunnable<void, void, OwnerType>: public ActiveRunnableBase
/// This class is used by ActiveMethod.
/// See the ActiveMethod class for more information.
{
public:
typedef void (OwnerType::*Callback)();
typedef ActiveResult<void> 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

View File

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

View File

@ -0,0 +1,206 @@
//
// Activity.h
//
// Library: Foundation
// Package: Threading
// Module: ActiveObjects
//
// Definition of the Activity template class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Activity_INCLUDED
#define Foundation_Activity_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/RunnableAdapter.h"
#include "Poco/ThreadPool.h"
#include "Poco/Event.h"
#include "Poco/Mutex.h"
namespace Poco {
template <class C>
class Activity: public Runnable
/// This template class helps to implement active objects.
/// An active object uses threads to decouple method
/// execution from method invocation, or to perform tasks
/// autonomously, without intervention of a caller.
///
/// An activity is a (typically longer running) method
/// that executes within its own task. Activities can
/// be started automatically (upon object construction)
/// or manually at a later time. Activities can also
/// be stopped at any time. However, to make stopping
/// an activity work, the method implementing the
/// activity has to check periodically whether it
/// has been requested to stop, and if so, return.
/// Activities are stopped before the object they belong to is
/// destroyed. Methods implementing activities cannot have arguments
/// or return values.
///
/// Activity objects are used as follows:
///
/// class ActiveObject
/// {
/// public:
/// ActiveObject():
/// _activity(this, &ActiveObject::runActivity)
/// {
/// ...
/// }
///
/// ...
///
/// protected:
/// void runActivity()
/// {
/// while (!_activity.isStopped())
/// {
/// ...
/// }
/// }
///
/// private:
/// Activity<ActiveObject> _activity;
/// };
{
public:
typedef RunnableAdapter<C> RunnableAdapterType;
typedef typename RunnableAdapterType::Callback Callback;
Activity(C* pOwner, Callback method):
_pOwner(pOwner),
_runnable(*pOwner, method),
_stopped(true),
_running(false),
_done(Event::EVENT_MANUALRESET)
/// Creates the activity. Call start() to
/// start it.
{
poco_check_ptr (pOwner);
}
~Activity()
/// Stops and destroys the activity.
{
try
{
stop();
wait();
}
catch (...)
{
poco_unexpected();
}
}
void start()
/// Starts the activity by acquiring a
/// thread for it from the default thread pool.
{
start(ThreadPool::defaultPool());
}
void start(ThreadPool& pool)
{
FastMutex::ScopedLock lock(_mutex);
if (!_running)
{
_done.reset();
_stopped = false;
_running = true;
try
{
pool.start(*this);
}
catch (...)
{
_running = false;
throw;
}
}
}
void stop()
/// Requests to stop the activity.
{
_stopped = true;
}
void wait()
/// Waits for the activity to complete.
{
if (_running)
{
_done.wait();
}
}
void wait(long milliseconds)
/// Waits the given interval for the activity to complete.
/// An TimeoutException is thrown if the activity does not
/// complete within the given interval.
{
if (_running)
{
_done.wait(milliseconds);
}
}
bool isStopped() const
/// Returns true if the activity has been requested to stop.
{
return _stopped;
}
bool isRunning() const
/// Returns true if the activity is running.
{
return _running;
}
protected:
void run()
{
try
{
_runnable.run();
}
catch (...)
{
_running = false;
_done.set();
throw;
}
_running = false;
_done.set();
}
private:
Activity();
Activity(const Activity&);
Activity& operator = (const Activity&);
C* _pOwner;
RunnableAdapterType _runnable;
std::atomic<bool> _stopped;
std::atomic<bool> _running;
Event _done;
FastMutex _mutex;
};
} // namespace Poco
#endif // Foundation_Activity_INCLUDED

View File

@ -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 <type_traits>
#define POCO_HAVE_ALIGNMENT
#endif // Foundation_Alignment_INCLUDED

View File

@ -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 <algorithm>
#include <typeinfo>
#include <cstring>
namespace Poco {
class Any;
namespace Dynamic {
class Var;
class VarHolder;
template <class T> class VarHolderImpl;
}
#ifndef POCO_NO_SOO
template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE>
union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
/// object optimization, when enabled).
///
/// If Holder<Type> 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<PlaceholderT*>(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<SizeV + 1>::type AlignerType;
PlaceholderT* pHolder;
mutable char holder[SizeV + 1];
AlignerType aligner;
friend class Any;
friend class Dynamic::Var;
friend class Dynamic::VarHolder;
template <class> friend class Dynamic::VarHolderImpl;
};
#else // !POCO_NO_SOO
template <typename PlaceholderT>
union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
/// object optimization, when enabled).
///
/// If Holder<Type> 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 <class> 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<typename ValueType>
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<typename ValueType>
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<ValueHolder>*) const = 0;
};
template<typename ValueType>
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<ValueHolder>* pPlaceholder) const
{
if ((sizeof(Holder<ValueType>) <= 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<typename ValueType>
void construct(const ValueType& value)
{
if (sizeof(Holder<ValueType>) <= Placeholder<ValueType>::Size::value)
{
new (reinterpret_cast<ValueHolder*>(_valueHolder.holder)) Holder<ValueType>(value);
_valueHolder.setLocal(true);
}
else
{
_valueHolder.pHolder = new Holder<ValueType>(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> _valueHolder;
#else // if POCO_NO_SOO
Any(): _pHolder(0)
/// Creates an empty any type.
{
}
template <typename ValueType>
Any(const ValueType& value):
_pHolder(new Holder<ValueType>(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 <typename ValueType>
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 <typename ValueType>
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 <typename ValueType>
friend ValueType* AnyCast(Any*);
template <typename ValueType>
friend ValueType* UnsafeAnyCast(Any*);
template <typename ValueType>
friend const ValueType& RefAnyCast(const Any&);
template <typename ValueType>
friend ValueType& RefAnyCast(Any&);
template <typename ValueType>
friend ValueType AnyCast(Any&);
};
template <typename ValueType>
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<MyType*>(pAny).
/// Will return NULL if the cast fails, i.e. types don't match.
{
return operand && operand->type() == typeid(ValueType)
? &static_cast<Any::Holder<ValueType>*>(operand->content())->_held
: 0;
}
template <typename ValueType>
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<MyType*>(pAny).
/// Will return NULL if the cast fails, i.e. types don't match.
{
return AnyCast<ValueType>(const_cast<Any*>(operand));
}
template <typename ValueType>
ValueType AnyCast(Any& operand)
/// AnyCast operator used to extract a copy of the ValueType from an Any&.
///
/// Example Usage:
/// MyType tmp = AnyCast<MyType>(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<ValueType>::TYPE NonRef;
NonRef* result = AnyCast<NonRef>(&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 <typename ValueType>
ValueType AnyCast(const Any& operand)
/// AnyCast operator used to extract a copy of the ValueType from an const Any&.
///
/// Example Usage:
/// MyType tmp = AnyCast<MyType>(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<ValueType>::TYPE NonRef;
return AnyCast<NonRef&>(const_cast<Any&>(operand));
}
template <typename ValueType>
const ValueType& RefAnyCast(const Any & operand)
/// AnyCast operator used to return a const reference to the internal data.
///
/// Example Usage:
/// const MyType& tmp = RefAnyCast<MyType>(anAny);
{
ValueType* result = AnyCast<ValueType>(const_cast<Any*>(&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 <typename ValueType>
ValueType& RefAnyCast(Any& operand)
/// AnyCast operator used to return a reference to the internal data.
///
/// Example Usage:
/// MyType& tmp = RefAnyCast<MyType>(anAny);
{
ValueType* result = AnyCast<ValueType>(&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 <typename ValueType>
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<Any::Holder<ValueType>*>(operand->content())->_held;
}
template <typename ValueType>
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<ValueType>(const_cast<Any*>(operand));
}
} // namespace Poco
#endif

View File

@ -0,0 +1,146 @@
//
// ArchiveStrategy.h
//
// Library: Foundation
// Package: Logging
// Module: FileChannel
//
// Definition of the ArchiveStrategy class and subclasses.
//
// Copyright (c) 2004-2008, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ArchiveStrategy_INCLUDED
#define Foundation_ArchiveStrategy_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/LogFile.h"
#include "Poco/File.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/NumberFormatter.h"
namespace Poco {
class ArchiveCompressor;
class Foundation_API ArchiveStrategy
/// The ArchiveStrategy is used by FileChannel
/// to rename a rotated log file for archiving.
///
/// Archived files can be automatically compressed,
/// using the gzip file format.
{
public:
ArchiveStrategy();
virtual ~ArchiveStrategy();
virtual LogFile* archive(LogFile* pFile) = 0;
/// Renames the given log file for archiving
/// and creates and returns a new log file.
/// The given LogFile object is deleted.
void compress(bool flag = true);
/// Enables or disables compression of archived files.
protected:
void moveFile(const std::string& oldName, const std::string& newName);
bool exists(const std::string& name);
private:
ArchiveStrategy(const ArchiveStrategy&);
ArchiveStrategy& operator = (const ArchiveStrategy&);
bool _compress;
ArchiveCompressor* _pCompressor;
};
class Foundation_API ArchiveByNumberStrategy: public ArchiveStrategy
/// A monotonic increasing number is appended to the
/// log file name. The most recent archived file
/// always has the number zero.
{
public:
ArchiveByNumberStrategy();
~ArchiveByNumberStrategy();
LogFile* archive(LogFile* pFile);
};
template <class DT>
class ArchiveByTimestampStrategy: public ArchiveStrategy
/// A timestamp (YYYYMMDDhhmmssiii) is appended to archived
/// log files.
{
public:
ArchiveByTimestampStrategy()
{
}
~ArchiveByTimestampStrategy()
{
}
LogFile* archive(LogFile* pFile)
/// Archives the file by appending the current timestamp to the
/// file name. If the new file name exists, additionally a monotonic
/// increasing number is appended to the log file name.
{
std::string path = pFile->path();
delete pFile;
std::string archPath = path;
archPath.append(".");
DateTimeFormatter::append(archPath, DT().timestamp(), "%Y%m%d%H%M%S%i");
if (exists(archPath)) archiveByNumber(archPath);
else moveFile(path, archPath);
return new LogFile(path);
}
private:
void archiveByNumber(const std::string& basePath)
/// A monotonic increasing number is appended to the
/// log file name. The most recent archived file
/// always has the number zero.
{
int n = -1;
std::string path;
do
{
path = basePath;
path.append(".");
NumberFormatter::append(path, ++n);
}
while (exists(path));
while (n >= 0)
{
std::string oldPath = basePath;
if (n > 0)
{
oldPath.append(".");
NumberFormatter::append(oldPath, n - 1);
}
std::string newPath = basePath;
newPath.append(".");
NumberFormatter::append(newPath, n);
moveFile(oldPath, newPath);
--n;
}
}
};
} // namespace Poco
#endif // Foundation_ArchiveStrategy_INCLUDED

View File

@ -0,0 +1,260 @@
//
// Array.h
//
// Library: Foundation
// Package: Core
// Module: Array
//
// Definition of the Array class
//
// Copyright (c) 2004-2008, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
// ------------------------------------------------------------------------------
// (C) Copyright Nicolai M. Josuttis 2001.
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// ------------------------------------------------------------------------------
#ifndef Foundation_Array_INCLUDED
#define Foundation_Array_INCLUDED
#include "Poco/Exception.h"
#include "Poco/Bugcheck.h"
#include <algorithm>
namespace Poco {
template<class T, std::size_t N>
class Array
/// STL container like C-style array replacement class.
///
/// This implementation is based on the idea of Nicolai Josuttis.
/// His original implementation can be found at http://www.josuttis.com/cppcode/array.html .
{
public:
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
iterator begin()
{
return elems;
}
const_iterator begin() const
{
return elems;
}
iterator end()
{
return elems+N;
}
const_iterator end() const
{
return elems+N;
}
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
reference operator[](size_type i)
/// Element access without range check. If the index is not small than the given size, the behavior is undefined.
{
poco_assert( i < N && "out of range" );
return elems[i];
}
const_reference operator[](size_type i) const
/// Element access without range check. If the index is not small than the given size, the behavior is undefined.
{
poco_assert( i < N && "out of range" );
return elems[i];
}
reference at(size_type i)
/// Element access with range check. Throws Poco::InvalidArgumentException if the index is over range.
{
if(i>=size())
throw Poco::InvalidArgumentException("Array::at() range check failed: index is over range");
return elems[i];
}
const_reference at(size_type i) const
/// Element access with range check. Throws Poco::InvalidArgumentException if the index is over range.
{
if(i>=size())
throw Poco::InvalidArgumentException("Array::at() range check failed: index is over range");
return elems[i];
}
reference front()
{
return elems[0];
}
const_reference front() const
{
return elems[0];
}
reference back()
{
return elems[N-1];
}
const_reference back() const
{
return elems[N-1];
}
static size_type size()
{
return N;
}
static bool empty()
{
return false;
}
static size_type max_size()
{
return N;
}
enum { static_size = N };
void swap (Array<T,N>& y)
{
std::swap_ranges(begin(),end(),y.begin());
}
const T* data() const
/// Direct access to data (read-only)
{
return elems;
}
T* data()
{
return elems;
}
T* c_array()
{
/// Use array as C array (direct read/write access to data)
return elems;
}
template <typename Other>
Array<T,N>& operator= (const Array<Other,N>& rhs)
/// Assignment with type conversion
{
std::copy(rhs.begin(),rhs.end(), begin());
return *this;
}
void assign (const T& value)
/// Assign one value to all elements
{
std::fill_n(begin(),size(),value);
}
public:
T elems[N];
/// Fixed-size array of elements of type T, public specifier used to make this class a aggregate.
};
// comparisons
template<class T, std::size_t N>
bool operator== (const Array<T,N>& x, const Array<T,N>& y)
{
return std::equal(x.begin(), x.end(), y.begin());
}
template<class T, std::size_t N>
bool operator< (const Array<T,N>& x, const Array<T,N>& y)
{
return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
}
template<class T, std::size_t N>
bool operator!= (const Array<T,N>& x, const Array<T,N>& y)
{
return !(x==y);
}
template<class T, std::size_t N>
bool operator> (const Array<T,N>& x, const Array<T,N>& y)
{
return y<x;
}
template<class T, std::size_t N>
bool operator<= (const Array<T,N>& x, const Array<T,N>& y)
{
return !(y<x);
}
template<class T, std::size_t N>
bool operator>= (const Array<T,N>& x, const Array<T,N>& y)
{
return !(x<y);
}
template<class T, std::size_t N>
inline void swap (Array<T,N>& x, Array<T,N>& y)
/// global swap()
{
x.swap(y);
}
}// namespace Poco
#endif // Foundation_Array_INCLUDED

View File

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

View File

@ -0,0 +1,119 @@
//
// AsyncChannel.h
//
// Library: Foundation
// Package: Logging
// Module: AsyncChannel
//
// Definition of the AsyncChannel class.
//
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AsyncChannel_INCLUDED
#define Foundation_AsyncChannel_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Channel.h"
#include "Poco/Thread.h"
#include "Poco/Mutex.h"
#include "Poco/Runnable.h"
#include "Poco/AutoPtr.h"
#include "Poco/NotificationQueue.h"
namespace Poco {
class Foundation_API AsyncChannel: public Channel, public Runnable
/// A channel uses a separate thread for logging.
///
/// Using this channel can help to improve the performance of
/// applications that produce huge amounts of log messages or
/// that write log messages to multiple channels simultaneously.
///
/// All log messages are put into a queue and this queue is
/// then processed by a separate thread.
{
public:
using Ptr = AutoPtr<AsyncChannel>;
AsyncChannel(Channel::Ptr pChannel = 0, Thread::Priority prio = Thread::PRIO_NORMAL);
/// Creates the AsyncChannel and connects it to
/// the given channel.
void setChannel(Channel::Ptr pChannel);
/// Connects the AsyncChannel to the given target channel.
/// All messages will be forwarded to this channel.
Channel::Ptr getChannel() const;
/// Returns the target channel.
void open();
/// Opens the channel and creates the
/// background logging thread.
void close();
/// Closes the channel and stops the background
/// logging thread.
void log(const Message& msg);
/// Queues the message for processing by the
/// background thread.
void setProperty(const std::string& name, const std::string& value);
/// Sets or changes a configuration property.
///
/// The "channel" property allows setting the target
/// channel via the LoggingRegistry.
/// The "channel" property is set-only.
///
/// The "priority" property allows setting the thread
/// priority. The following values are supported:
/// * lowest
/// * low
/// * normal (default)
/// * high
/// * highest
///
/// The "priority" property is set-only.
///
/// The "queueSize" property allows to limit the number
/// of messages in the queue. If the queue is full and
/// new messages are logged, these are dropped until the
/// queue has free capacity again. The number of dropped
/// messages is recorded, and a log message indicating the
/// number of dropped messages will be generated when the
/// queue has free capacity again.
/// In addition to an unsigned integer specifying the size,
/// this property can have the values "none" or "unlimited",
/// which disable the queue size limit. A size of 0 also
/// removes the limit.
///
/// The "queueSize" property is set-only.
protected:
~AsyncChannel();
void run();
void setPriority(const std::string& value);
private:
Channel::Ptr _pChannel;
Thread _thread;
FastMutex _threadMutex;
FastMutex _channelMutex;
NotificationQueue _queue;
std::size_t _queueSize = 0;
std::size_t _dropCount = 0;
};
} // namespace Poco
#endif // Foundation_AsyncChannel_INCLUDED

View File

@ -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 <atomic>
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<int> _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

View File

@ -0,0 +1,121 @@
//
// AtomicFlag.h
//
// Library: Foundation
// Package: Core
// Module: AtomicFlag
//
// Definition of the AtomicFlag class.
//
// Copyright (c) 2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AtomicFlag_INCLUDED
#define Foundation_AtomicFlag_INCLUDED
#include "Poco/Foundation.h"
#include <atomic>
namespace Poco {
class Foundation_API AtomicFlag
/// This class implements an atomic boolean flag by wrapping
/// the std::atomic_flag. It is guaranteed to be thread-safe
/// and lock-free.
///
/// Only default-construction is allowed, objects of this
/// class are not copyable, assignable or movable.
///
/// Note that this class is not a replacement for (atomic)
/// bool type because its value can not be read without also
/// being set to true. However, after being set (either
/// explicitly, through the set() call or implicitly, via
/// operator bool()), it can be reset and reused.
///
/// The class is useful in scenarios such as busy-wait or
/// one-off code blocks, e.g.:
///
/// class MyClass
/// {
/// public:
/// void myFunc()
/// {
/// if (!_beenHere) doOnce();
/// doMany();
/// }
///
/// void doOnce() { /* executed once */ }
///
/// void doMany() { /* executed multiple times */ }
///
/// private:
/// AtomicFlag _beenHere;
/// }
///
/// MyClass myClass;
/// int i = 0;
/// while (++i < 10) myClass.myFunc();
{
public:
AtomicFlag() = default;
/// Creates AtomicFlag.
~AtomicFlag() = default;
/// Destroys AtomicFlag.
bool set();
/// Sets the flag to true and returns previously
/// held value.
void reset();
/// Resets the flag to false.
operator bool ();
/// Sets the flag to true and returns previously
/// held value.
private:
AtomicFlag(const AtomicFlag&) = delete;
AtomicFlag& operator = (const AtomicFlag&) = delete;
AtomicFlag(AtomicFlag&&) = delete;
AtomicFlag& operator = (AtomicFlag&&) = delete;
std::atomic_flag _flag = ATOMIC_FLAG_INIT;
};
//
// inlines
//
inline bool AtomicFlag::set()
{
return _flag.test_and_set(std::memory_order_acquire);
}
inline void AtomicFlag::reset()
{
_flag.clear(std::memory_order_release);
}
inline AtomicFlag::operator bool ()
{
return set();
}
} // namespace Poco
#endif // Foundation_AtomicFlag_INCLUDED

View File

@ -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 <algorithm>
#include <cstddef>
namespace Poco {
template <class C>
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 <class Other>
AutoPtr(const AutoPtr<Other>& ptr): _ptr(const_cast<Other*>(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 <class Other>
AutoPtr& assign(const AutoPtr<Other>& ptr)
{
if (ptr.get() != _ptr)
{
if (_ptr) _ptr->release();
_ptr = const_cast<Other*>(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 <class Other>
void reset(const AutoPtr<Other>& ptr)
{
assign<Other>(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 <class Other>
AutoPtr& operator = (const AutoPtr<Other>& ptr)
{
return assign<Other>(ptr);
}
void swap(AutoPtr& ptr)
{
std::swap(_ptr, ptr._ptr);
}
template <class Other>
AutoPtr<Other> 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> super(new Sub());
/// AutoPtr<Sub> sub = super.cast<Sub>();
/// poco_assert (sub.get());
{
Other* pOther = dynamic_cast<Other*>(_ptr);
return AutoPtr<Other>(pOther, true);
}
template <class Other>
AutoPtr<Other> unsafeCast() const
/// Casts the AutoPtr via a static cast to the given type.
/// Example: (assume class Sub: public Super)
/// AutoPtr<Super> super(new Sub());
/// AutoPtr<Sub> sub = super.unsafeCast<Sub>();
/// poco_assert (sub.get());
{
Other* pOther = static_cast<Other*>(_ptr);
return AutoPtr<Other>(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 <class C>
inline void swap(AutoPtr<C>& p1, AutoPtr<C>& p2)
{
p1.swap(p2);
}
template<typename T, typename... Args>
AutoPtr<T> makeAuto(Args&&... args)
{
return AutoPtr<T>(new T(std::forward<Args>(args)...));
}
} // namespace Poco
#endif // Foundation_AutoPtr_INCLUDED

View File

@ -0,0 +1,86 @@
//
// AutoReleasePool.h
//
// Library: Foundation
// Package: Core
// Module: AutoReleasePool
//
// Definition of the AutoReleasePool class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AutoReleasePool_INCLUDED
#define Foundation_AutoReleasePool_INCLUDED
#include "Poco/Foundation.h"
#include <list>
namespace Poco {
template <class C>
class AutoReleasePool
/// An AutoReleasePool implements simple garbage collection for
/// reference-counted objects.
/// It temporarily takes ownership of reference-counted objects that
/// nobody else wants to take ownership of and releases them
/// at a later, appropriate point in time.
///
/// Note: The correct way to add an object hold by an AutoPtr<> to
/// an AutoReleasePool is by invoking the AutoPtr's duplicate()
/// method. Example:
/// AutoReleasePool<C> arp;
/// AutoPtr<C> ptr = new C;
/// ...
/// arp.add(ptr.duplicate());
{
public:
AutoReleasePool()
/// Creates the AutoReleasePool.
{
}
~AutoReleasePool()
/// Destroys the AutoReleasePool and releases
/// all objects it currently holds.
{
release();
}
void add(C* pObject)
/// Adds the given object to the AutoReleasePool.
/// The object's reference count is not modified
{
if (pObject)
_list.push_back(pObject);
}
void release()
/// Releases all objects the AutoReleasePool currently holds
/// by calling each object's release() method.
{
while (!_list.empty())
{
_list.front()->release();
_list.pop_front();
}
}
private:
typedef std::list<C*> ObjectList;
ObjectList _list;
};
} // namespace Poco
#endif // Foundation_AutoReleasePool_INCLUDED

View File

@ -0,0 +1,106 @@
//
// Base32Decoder.h
//
// Library: Foundation
// Package: Streams
// Module: Base32
//
// Definition of class Base32Decoder.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Base32Decoder_INCLUDED
#define Foundation_Base32Decoder_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/UnbufferedStreamBuf.h"
#include <istream>
namespace Poco {
class Foundation_API Base32DecoderBuf: public UnbufferedStreamBuf
/// This streambuf base32-decodes all data read
/// from the istream connected to it.
///
/// Note: For performance reasons, the characters
/// are read directly from the given istream's
/// underlying streambuf, so the state
/// of the istream will not reflect that of
/// its streambuf.
{
public:
Base32DecoderBuf(std::istream& istr);
~Base32DecoderBuf();
private:
int readFromDevice();
int readOne();
unsigned char _group[8];
int _groupLength;
int _groupIndex;
std::streambuf& _buf;
static unsigned char IN_ENCODING[256];
static bool IN_ENCODING_INIT;
private:
Base32DecoderBuf(const Base32DecoderBuf&);
Base32DecoderBuf& operator = (const Base32DecoderBuf&);
};
class Foundation_API Base32DecoderIOS: public virtual std::ios
/// The base class for Base32Decoder.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
Base32DecoderIOS(std::istream& istr);
~Base32DecoderIOS();
Base32DecoderBuf* rdbuf();
protected:
Base32DecoderBuf _buf;
private:
Base32DecoderIOS(const Base32DecoderIOS&);
Base32DecoderIOS& operator = (const Base32DecoderIOS&);
};
class Foundation_API Base32Decoder: public Base32DecoderIOS, public std::istream
/// This istream base32-decodes all data
/// read from the istream connected to it.
///
/// The class implements RFC 4648 - https://tools.ietf.org/html/rfc4648
///
/// Note: For performance reasons, the characters
/// are read directly from the given istream's
/// underlying streambuf, so the state
/// of the istream will not reflect that of
/// its streambuf.
{
public:
Base32Decoder(std::istream& istr);
~Base32Decoder();
private:
Base32Decoder(const Base32Decoder&);
Base32Decoder& operator = (const Base32Decoder&);
};
} // namespace Poco
#endif // Foundation_Base32Decoder_INCLUDED

View File

@ -0,0 +1,112 @@
//
// Base32Encoder.h
//
// Library: Foundation
// Package: Streams
// Module: Base32
//
// Definition of class Base32Encoder.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Base32Encoder_INCLUDED
#define Foundation_Base32Encoder_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/UnbufferedStreamBuf.h"
#include <ostream>
namespace Poco {
class Foundation_API Base32EncoderBuf: public UnbufferedStreamBuf
/// This streambuf base32-encodes all data written
/// to it and forwards it to a connected
/// ostream.
///
/// Note: The characters are directly written
/// to the ostream's streambuf, thus bypassing
/// the ostream. The ostream's state is therefore
/// not updated to match the buffer's state.
{
public:
Base32EncoderBuf(std::ostream& ostr, bool padding = true);
~Base32EncoderBuf();
int close();
/// Closes the stream buffer.
private:
int writeToDevice(char c);
unsigned char _group[5];
int _groupLength;
std::streambuf& _buf;
bool _doPadding;
static const unsigned char OUT_ENCODING[32];
friend class Base32DecoderBuf;
Base32EncoderBuf(const Base32EncoderBuf&);
Base32EncoderBuf& operator = (const Base32EncoderBuf&);
};
class Foundation_API Base32EncoderIOS: public virtual std::ios
/// The base class for Base32Encoder.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
Base32EncoderIOS(std::ostream& ostr, bool padding = true);
~Base32EncoderIOS();
int close();
Base32EncoderBuf* rdbuf();
protected:
Base32EncoderBuf _buf;
private:
Base32EncoderIOS(const Base32EncoderIOS&);
Base32EncoderIOS& operator = (const Base32EncoderIOS&);
};
class Foundation_API Base32Encoder: public Base32EncoderIOS, public std::ostream
/// This ostream base32-encodes all data
/// written to it and forwards it to
/// a connected ostream.
/// Always call close() when done
/// writing data, to ensure proper
/// completion of the encoding operation.
///
/// The class implements RFC 4648 - https://tools.ietf.org/html/rfc4648
///
/// Note: The characters are directly written
/// to the ostream's streambuf, thus bypassing
/// the ostream. The ostream's state is therefore
/// not updated to match the buffer's state.
{
public:
Base32Encoder(std::ostream& ostr, bool padding = true);
~Base32Encoder();
private:
Base32Encoder(const Base32Encoder&);
Base32Encoder& operator = (const Base32Encoder&);
};
} // namespace Poco
#endif // Foundation_Base32Encoder_INCLUDED

View File

@ -0,0 +1,110 @@
//
// Base64Decoder.h
//
// Library: Foundation
// Package: Streams
// Module: Base64
//
// Definition of class Base64Decoder.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Base64Decoder_INCLUDED
#define Foundation_Base64Decoder_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/UnbufferedStreamBuf.h"
#include <istream>
namespace Poco {
class Foundation_API Base64DecoderBuf: public UnbufferedStreamBuf
/// This streambuf base64-decodes all data read
/// from the istream connected to it.
///
/// Note: For performance reasons, the characters
/// are read directly from the given istream's
/// underlying streambuf, so the state
/// of the istream will not reflect that of
/// its streambuf.
{
public:
Base64DecoderBuf(std::istream& istr, int options = 0);
~Base64DecoderBuf();
private:
int readFromDevice();
int readOne();
int _options;
unsigned char _group[3];
int _groupLength;
int _groupIndex;
std::streambuf& _buf;
const unsigned char* _pInEncoding;
static unsigned char IN_ENCODING[256];
static bool IN_ENCODING_INIT;
static unsigned char IN_ENCODING_URL[256];
static bool IN_ENCODING_URL_INIT;
private:
Base64DecoderBuf(const Base64DecoderBuf&);
Base64DecoderBuf& operator = (const Base64DecoderBuf&);
};
class Foundation_API Base64DecoderIOS: public virtual std::ios
/// The base class for Base64Decoder.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
Base64DecoderIOS(std::istream& istr, int options = 0);
~Base64DecoderIOS();
Base64DecoderBuf* rdbuf();
protected:
Base64DecoderBuf _buf;
private:
Base64DecoderIOS(const Base64DecoderIOS&);
Base64DecoderIOS& operator = (const Base64DecoderIOS&);
};
class Foundation_API Base64Decoder: public Base64DecoderIOS, public std::istream
/// This istream base64-decodes all data
/// read from the istream connected to it.
///
/// The class implements RFC 4648 - https://tools.ietf.org/html/rfc4648
///
/// Note: For performance reasons, the characters
/// are read directly from the given istream's
/// underlying streambuf, so the state
/// of the istream will not reflect that of
/// its streambuf.
{
public:
Base64Decoder(std::istream& istr, int options = 0);
~Base64Decoder();
private:
Base64Decoder(const Base64Decoder&);
Base64Decoder& operator = (const Base64Decoder&);
};
} // namespace Poco
#endif // Foundation_Base64Decoder_INCLUDED

View File

@ -0,0 +1,140 @@
//
// Base64Encoder.h
//
// Library: Foundation
// Package: Streams
// Module: Base64
//
// Definition of class Base64Encoder.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Base64Encoder_INCLUDED
#define Foundation_Base64Encoder_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/UnbufferedStreamBuf.h"
#include <ostream>
namespace Poco {
enum Base64EncodingOptions
{
BASE64_URL_ENCODING = 0x01,
/// Use the URL and filename-safe alphabet,
/// replacing '+' with '-' and '/' with '_'.
///
/// Will also set line length to unlimited.
BASE64_NO_PADDING = 0x02
/// Do not append padding characters ('=') at end.
};
class Foundation_API Base64EncoderBuf: public UnbufferedStreamBuf
/// This streambuf base64-encodes all data written
/// to it and forwards it to a connected
/// ostream.
///
/// Note: The characters are directly written
/// to the ostream's streambuf, thus bypassing
/// the ostream. The ostream's state is therefore
/// not updated to match the buffer's state.
{
public:
Base64EncoderBuf(std::ostream& ostr, int options = 0);
~Base64EncoderBuf();
int close();
/// Closes the stream buffer.
void setLineLength(int lineLength);
/// Specify the line length.
///
/// After the given number of characters have been written,
/// a newline character will be written.
///
/// Specify 0 for an unlimited line length.
int getLineLength() const;
/// Returns the currently set line length.
private:
int writeToDevice(char c);
int _options;
unsigned char _group[3];
int _groupLength;
int _pos;
int _lineLength;
std::streambuf& _buf;
const unsigned char* _pOutEncoding;
static const unsigned char OUT_ENCODING[64];
static const unsigned char OUT_ENCODING_URL[64];
friend class Base64DecoderBuf;
Base64EncoderBuf(const Base64EncoderBuf&);
Base64EncoderBuf& operator = (const Base64EncoderBuf&);
};
class Foundation_API Base64EncoderIOS: public virtual std::ios
/// The base class for Base64Encoder.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
Base64EncoderIOS(std::ostream& ostr, int options = 0);
~Base64EncoderIOS();
int close();
Base64EncoderBuf* rdbuf();
protected:
Base64EncoderBuf _buf;
private:
Base64EncoderIOS(const Base64EncoderIOS&);
Base64EncoderIOS& operator = (const Base64EncoderIOS&);
};
class Foundation_API Base64Encoder: public Base64EncoderIOS, public std::ostream
/// This ostream base64-encodes all data
/// written to it and forwards it to
/// a connected ostream.
/// Always call close() when done
/// writing data, to ensure proper
/// completion of the encoding operation.
///
/// The class implements RFC 4648 - https://tools.ietf.org/html/rfc4648
///
/// Note: The characters are directly written
/// to the ostream's streambuf, thus bypassing
/// the ostream. The ostream's state is therefore
/// not updated to match the buffer's state.
{
public:
Base64Encoder(std::ostream& ostr, int options = 0);
~Base64Encoder();
private:
Base64Encoder(const Base64Encoder&);
Base64Encoder& operator = (const Base64Encoder&);
};
} // namespace Poco
#endif // Foundation_Base64Encoder_INCLUDED

View File

@ -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 TArgs, class TMutex = FastMutex>
class BasicEvent: public AbstractEvent <
TArgs, DefaultStrategy<TArgs, AbstractDelegate<TArgs>>,
AbstractDelegate<TArgs>,
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

View File

@ -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 <vector>
#include <istream>
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 <typename T>
BinaryReader& operator >> (std::vector<T>& 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 <typename T>
class BasicMemoryBinaryReader : public BinaryReader
/// A convenient wrapper for using Buffer and MemoryStream with BinaryReader.
{
public:
BasicMemoryBinaryReader(const Buffer<T>& data, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
BinaryReader(_istr, byteOrder),
_data(data),
_istr(data.begin(), data.capacity())
{
}
BasicMemoryBinaryReader(const Buffer<T>& data, TextEncoding& encoding, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
BinaryReader(_istr, encoding, byteOrder),
_data(data),
_istr(data.begin(), data.capacity())
{
}
~BasicMemoryBinaryReader()
{
}
const Buffer<T>& data() const
{
return _data;
}
const MemoryInputStream& stream() const
{
return _istr;
}
MemoryInputStream& stream()
{
return _istr;
}
private:
const Buffer<T>& _data;
MemoryInputStream _istr;
};
typedef BasicMemoryBinaryReader<char> 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

View File

@ -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 <vector>
#include <ostream>
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 <typename T>
BinaryWriter& operator << (const std::vector<T>& value)
{
Poco::UInt32 size(static_cast<Poco::UInt32>(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 <typename T>
class BasicMemoryBinaryWriter: public BinaryWriter
/// A convenient wrapper for using Buffer and MemoryStream with BinarWriter.
{
public:
BasicMemoryBinaryWriter(Buffer<T>& data, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
BinaryWriter(_ostr, byteOrder),
_data(data),
_ostr(data.begin(), data.capacity())
{
}
BasicMemoryBinaryWriter(Buffer<T>& 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<T>& data()
{
return _data;
}
const Buffer<T>& data() const
{
return _data;
}
const MemoryOutputStream& stream() const
{
return _ostr;
}
MemoryOutputStream& stream()
{
return _ostr;
}
private:
Buffer<T>& _data;
MemoryOutputStream _ostr;
};
typedef BasicMemoryBinaryWriter<char> 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

View File

@ -0,0 +1,361 @@
//
// 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 <cstring>
#include <cstddef>
namespace Poco {
template <class T>
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)
{
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)
{
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 (std::memcmp(_ptr, other._ptr, _used * sizeof(T)) == 0)
{
return true;
}
}
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

View File

@ -0,0 +1,52 @@
//
// BufferAllocator.h
//
// Library: Foundation
// Package: Streams
// Module: BufferAllocator
//
// Definition of the BufferAllocator class.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_BufferAllocator_INCLUDED
#define Foundation_BufferAllocator_INCLUDED
#include "Poco/Foundation.h"
#include <ios>
#include <cstddef>
namespace Poco {
template <typename ch>
class BufferAllocator
/// The BufferAllocator used if no specific
/// BufferAllocator has been specified.
{
public:
typedef ch char_type;
static char_type* allocate(std::streamsize size)
{
return new char_type[static_cast<std::size_t>(size)];
}
static void deallocate(char_type* ptr, std::streamsize /*size*/) noexcept
{
delete [] ptr;
}
};
} // namespace Poco
#endif // Foundation_BufferAllocator_INCLUDED

View File

@ -0,0 +1,181 @@
//
// BufferedBidirectionalStreamBuf.h
//
// Library: Foundation
// Package: Streams
// Module: StreamBuf
//
// Definition of template BasicBufferedBidirectionalStreamBuf and class BufferedBidirectionalStreamBuf.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_BufferedBidirectionalStreamBuf_INCLUDED
#define Foundation_BufferedBidirectionalStreamBuf_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/BufferAllocator.h"
#include "Poco/StreamUtil.h"
#include <streambuf>
#include <iosfwd>
#include <ios>
namespace Poco {
template <typename ch, typename tr, typename ba = BufferAllocator<ch>>
class BasicBufferedBidirectionalStreamBuf: public std::basic_streambuf<ch, tr>
/// This is an implementation of a buffered bidirectional
/// streambuf that greatly simplifies the implementation of
/// custom streambufs of various kinds.
/// Derived classes only have to override the methods
/// readFromDevice() or writeToDevice().
///
/// In contrast to BasicBufferedStreambuf, this class supports
/// simultaneous read and write access, so in addition to
/// istream and ostream this streambuf can also be used
/// for implementing an iostream.
{
protected:
typedef std::basic_streambuf<ch, tr> Base;
typedef std::basic_ios<ch, tr> IOS;
typedef ch char_type;
typedef tr char_traits;
typedef ba Allocator;
typedef typename Base::int_type int_type;
typedef typename Base::pos_type pos_type;
typedef typename Base::off_type off_type;
typedef typename IOS::openmode openmode;
public:
BasicBufferedBidirectionalStreamBuf(std::streamsize bufferSize, openmode mode):
_bufsize(bufferSize),
_pReadBuffer(Allocator::allocate(_bufsize)),
_pWriteBuffer(Allocator::allocate(_bufsize)),
_mode(mode)
{
resetBuffers();
}
~BasicBufferedBidirectionalStreamBuf()
{
Allocator::deallocate(_pReadBuffer, _bufsize);
Allocator::deallocate(_pWriteBuffer, _bufsize);
}
virtual int_type overflow(int_type c)
{
if (!(_mode & IOS::out)) return char_traits::eof();
if (flushBuffer() == std::streamsize(-1)) return char_traits::eof();
if (c != char_traits::eof())
{
*this->pptr() = char_traits::to_char_type(c);
this->pbump(1);
}
return c;
}
virtual int_type underflow()
{
if (!(_mode & IOS::in)) return char_traits::eof();
if (this->gptr() && (this->gptr() < this->egptr()))
return char_traits::to_int_type(*this->gptr());
int putback = int(this->gptr() - this->eback());
if (putback > 4) putback = 4;
char_traits::move(_pReadBuffer + (4 - putback), this->gptr() - putback, putback);
int n = readFromDevice(_pReadBuffer + 4, _bufsize - 4);
if (n <= 0) return char_traits::eof();
this->setg(_pReadBuffer + (4 - putback), _pReadBuffer + 4, _pReadBuffer + 4 + n);
// return next character
return char_traits::to_int_type(*this->gptr());
}
virtual int sync()
{
if (this->pptr() && this->pptr() > this->pbase())
{
if (flushBuffer() == -1) return -1;
}
return 0;
}
protected:
void setMode(openmode mode)
{
_mode = mode;
}
openmode getMode() const
{
return _mode;
}
void resetBuffers()
{
this->setg(_pReadBuffer + 4, _pReadBuffer + 4, _pReadBuffer + 4);
this->setp(_pWriteBuffer, _pWriteBuffer + _bufsize);
}
private:
virtual int readFromDevice(char_type* /*buffer*/, std::streamsize /*length*/)
{
return 0;
}
virtual int writeToDevice(const char_type* /*buffer*/, std::streamsize /*length*/)
{
return 0;
}
int flushBuffer()
{
int n = int(this->pptr() - this->pbase());
if (writeToDevice(this->pbase(), n) == n)
{
this->pbump(-n);
return n;
}
return -1;
}
std::streamsize _bufsize;
char_type* _pReadBuffer;
char_type* _pWriteBuffer;
openmode _mode;
BasicBufferedBidirectionalStreamBuf(const BasicBufferedBidirectionalStreamBuf&);
BasicBufferedBidirectionalStreamBuf& operator = (const BasicBufferedBidirectionalStreamBuf&);
};
//
// We provide an instantiation for char.
//
// Visual C++ needs a workaround - explicitly importing the template
// instantiation - to avoid duplicate symbols due to multiple
// instantiations in different libraries.
//
#if defined(_MSC_VER) && defined(POCO_DLL) && !defined(Foundation_EXPORTS)
template class Foundation_API BasicBufferedBidirectionalStreamBuf<char, std::char_traits<char>>;
#endif
typedef BasicBufferedBidirectionalStreamBuf<char, std::char_traits<char>> BufferedBidirectionalStreamBuf;
} // namespace Poco
#endif // Foundation_BufferedBidirectionalStreamBuf_INCLUDED

View File

@ -0,0 +1,180 @@
//
// BufferedStreamBuf.h
//
// Library: Foundation
// Package: Streams
// Module: StreamBuf
//
// Definition of template BasicBufferedStreamBuf and class BufferedStreamBuf.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_BufferedStreamBuf_INCLUDED
#define Foundation_BufferedStreamBuf_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/BufferAllocator.h"
#include "Poco/StreamUtil.h"
#include <streambuf>
#include <iosfwd>
#include <ios>
namespace Poco {
template <typename ch, typename tr, typename ba = BufferAllocator<ch>>
class BasicBufferedStreamBuf: public std::basic_streambuf<ch, tr>
/// This is an implementation of a buffered streambuf
/// that greatly simplifies the implementation of
/// custom streambufs of various kinds.
/// Derived classes only have to override the methods
/// readFromDevice() or writeToDevice().
///
/// This streambuf only supports unidirectional streams.
/// In other words, the BasicBufferedStreamBuf can be
/// used for the implementation of an istream or an
/// ostream, but not for an iostream.
{
protected:
typedef std::basic_streambuf<ch, tr> Base;
typedef std::basic_ios<ch, tr> IOS;
typedef ch char_type;
typedef tr char_traits;
typedef ba Allocator;
typedef typename Base::int_type int_type;
typedef typename Base::pos_type pos_type;
typedef typename Base::off_type off_type;
typedef typename IOS::openmode openmode;
public:
BasicBufferedStreamBuf(std::streamsize bufferSize, openmode mode):
_bufsize(bufferSize),
_pBuffer(Allocator::allocate(_bufsize)),
_mode(mode)
{
this->setg(_pBuffer + 4, _pBuffer + 4, _pBuffer + 4);
this->setp(_pBuffer, _pBuffer + _bufsize);
}
~BasicBufferedStreamBuf()
{
try
{
Allocator::deallocate(_pBuffer, _bufsize);
}
catch (...)
{
poco_unexpected();
}
}
virtual int_type overflow(int_type c)
{
if (!(_mode & IOS::out)) return char_traits::eof();
if (flushBuffer() == std::streamsize(-1)) return char_traits::eof();
if (c != char_traits::eof())
{
*this->pptr() = char_traits::to_char_type(c);
this->pbump(1);
}
return c;
}
virtual int_type underflow()
{
if (!(_mode & IOS::in)) return char_traits::eof();
if (this->gptr() && (this->gptr() < this->egptr()))
return char_traits::to_int_type(*this->gptr());
int putback = int(this->gptr() - this->eback());
if (putback > 4) putback = 4;
char_traits::move(_pBuffer + (4 - putback), this->gptr() - putback, putback);
int n = readFromDevice(_pBuffer + 4, _bufsize - 4);
if (n <= 0) return char_traits::eof();
this->setg(_pBuffer + (4 - putback), _pBuffer + 4, _pBuffer + 4 + n);
// return next character
return char_traits::to_int_type(*this->gptr());
}
virtual int sync()
{
if (this->pptr() && this->pptr() > this->pbase())
{
if (flushBuffer() == -1) return -1;
}
return 0;
}
protected:
void setMode(openmode mode)
{
_mode = mode;
}
openmode getMode() const
{
return _mode;
}
private:
virtual int readFromDevice(char_type* /*buffer*/, std::streamsize /*length*/)
{
return 0;
}
virtual int writeToDevice(const char_type* /*buffer*/, std::streamsize /*length*/)
{
return 0;
}
int flushBuffer()
{
int n = int(this->pptr() - this->pbase());
if (writeToDevice(this->pbase(), n) == n)
{
this->pbump(-n);
return n;
}
return -1;
}
std::streamsize _bufsize;
char_type* _pBuffer;
openmode _mode;
BasicBufferedStreamBuf(const BasicBufferedStreamBuf&);
BasicBufferedStreamBuf& operator = (const BasicBufferedStreamBuf&);
};
//
// We provide an instantiation for char.
//
// Visual C++ needs a workaround - explicitly importing the template
// instantiation - to avoid duplicate symbols due to multiple
// instantiations in different libraries.
//
#if defined(_MSC_VER) && defined(POCO_DLL) && !defined(Foundation_EXPORTS)
template class Foundation_API BasicBufferedStreamBuf<char, std::char_traits<char>>;
#endif
typedef BasicBufferedStreamBuf<char, std::char_traits<char>> BufferedStreamBuf;
} // namespace Poco
#endif // Foundation_BufferedStreamBuf_INCLUDED

View File

@ -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 <string>
#include <cstdlib>
#if defined(_DEBUG)
# include <iostream>
#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 <cstdlib> // 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 <boost/static_assert.hpp>
//
template <bool x>
struct POCO_STATIC_ASSERTION_FAILURE;
template <>
struct POCO_STATIC_ASSERTION_FAILURE<true>
{
enum
{
value = 1
};
};
template <int x>
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<sizeof(POCO_STATIC_ASSERTION_FAILURE<(bool) (B)>)> \
POCO_JOIN(poco_static_assert_typedef_, __LINE__) POCO_UNUSED
#endif
#endif // Foundation_Bugcheck_INCLUDED

View File

@ -0,0 +1,268 @@
//
// ByteOrder.h
//
// Library: Foundation
// Package: Core
// Module: ByteOrder
//
// Copyright (c) 2004-2014, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ByteOrder_INCLUDED
#define Foundation_ByteOrder_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Types.h"
#if defined(_MSC_VER)
#include <stdlib.h> // builtins
#endif
namespace Poco {
class Foundation_API ByteOrder
/// This class contains a number of static methods
/// to convert between big-endian and little-endian
/// integers of various sizes.
{
public:
static Int16 flipBytes(Int16 value);
static UInt16 flipBytes(UInt16 value);
static Int32 flipBytes(Int32 value);
static UInt32 flipBytes(UInt32 value);
static float flipBytes(float value);
static double flipBytes(double value);
#if defined(POCO_HAVE_INT64)
static Int64 flipBytes(Int64 value);
static UInt64 flipBytes(UInt64 value);
#endif
static Int16 toBigEndian(Int16 value);
static UInt16 toBigEndian (UInt16 value);
static Int32 toBigEndian(Int32 value);
static UInt32 toBigEndian (UInt32 value);
#if defined(POCO_HAVE_INT64)
static Int64 toBigEndian(Int64 value);
static UInt64 toBigEndian (UInt64 value);
#endif
static Int16 fromBigEndian(Int16 value);
static UInt16 fromBigEndian (UInt16 value);
static Int32 fromBigEndian(Int32 value);
static UInt32 fromBigEndian (UInt32 value);
#if defined(POCO_HAVE_INT64)
static Int64 fromBigEndian(Int64 value);
static UInt64 fromBigEndian (UInt64 value);
#endif
static Int16 toLittleEndian(Int16 value);
static UInt16 toLittleEndian (UInt16 value);
static Int32 toLittleEndian(Int32 value);
static UInt32 toLittleEndian (UInt32 value);
#if defined(POCO_HAVE_INT64)
static Int64 toLittleEndian(Int64 value);
static UInt64 toLittleEndian (UInt64 value);
#endif
static Int16 fromLittleEndian(Int16 value);
static UInt16 fromLittleEndian (UInt16 value);
static Int32 fromLittleEndian(Int32 value);
static UInt32 fromLittleEndian (UInt32 value);
#if defined(POCO_HAVE_INT64)
static Int64 fromLittleEndian(Int64 value);
static UInt64 fromLittleEndian (UInt64 value);
#endif
static Int16 toNetwork(Int16 value);
static UInt16 toNetwork (UInt16 value);
static Int32 toNetwork(Int32 value);
static UInt32 toNetwork (UInt32 value);
#if defined(POCO_HAVE_INT64)
static Int64 toNetwork(Int64 value);
static UInt64 toNetwork (UInt64 value);
#endif
static Int16 fromNetwork(Int16 value);
static UInt16 fromNetwork (UInt16 value);
static Int32 fromNetwork(Int32 value);
static UInt32 fromNetwork (UInt32 value);
#if defined(POCO_HAVE_INT64)
static Int64 fromNetwork(Int64 value);
static UInt64 fromNetwork (UInt64 value);
#endif
private:
template<typename T>
static T flip(T value)
{
T flip = value;
std::size_t halfSize = sizeof(T) / 2;
char* flipP = reinterpret_cast<char*>(&flip);
for (std::size_t i = 0; i < halfSize; i++)
{
std::swap(flipP[i], flipP[sizeof(T) - i - 1]);
}
return flip;
}
};
#if !defined(POCO_NO_BYTESWAP_BUILTINS)
#if defined(_MSC_VER)
#if (POCO_MSVC_VERSION > 71)
#define POCO_HAVE_MSC_BYTESWAP 1
#endif
#elif defined(__clang__)
#if __has_builtin(__builtin_bswap32)
#define POCO_HAVE_GCC_BYTESWAP 1
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
#define POCO_HAVE_GCC_BYTESWAP 1
#endif
#endif
//
// inlines
//
inline UInt16 ByteOrder::flipBytes(UInt16 value)
{
#if defined(POCO_HAVE_MSC_BYTESWAP)
return _byteswap_ushort(value);
#else
return ((value >> 8) & 0x00FF) | ((value << 8) & 0xFF00);
#endif
}
inline Int16 ByteOrder::flipBytes(Int16 value)
{
return Int16(flipBytes(UInt16(value)));
}
inline UInt32 ByteOrder::flipBytes(UInt32 value)
{
#if defined(POCO_HAVE_MSC_BYTESWAP)
return _byteswap_ulong(value);
#elif defined(POCO_HAVE_GCC_BYTESWAP)
return __builtin_bswap32(value);
#else
return ((value >> 24) & 0x000000FF) | ((value >> 8) & 0x0000FF00)
| ((value << 8) & 0x00FF0000) | ((value << 24) & 0xFF000000);
#endif
}
inline Int32 ByteOrder::flipBytes(Int32 value)
{
return Int32(flipBytes(UInt32(value)));
}
inline float ByteOrder::flipBytes(float value)
{
return flip(value);
}
inline double ByteOrder::flipBytes(double value)
{
return flip(value);
}
#if defined(POCO_HAVE_INT64)
inline UInt64 ByteOrder::flipBytes(UInt64 value)
{
#if defined(POCO_HAVE_MSC_BYTESWAP)
return _byteswap_uint64(value);
#elif defined(POCO_HAVE_GCC_BYTESWAP)
return __builtin_bswap64(value);
#else
UInt32 hi = UInt32(value >> 32);
UInt32 lo = UInt32(value & 0xFFFFFFFF);
return UInt64(flipBytes(hi)) | (UInt64(flipBytes(lo)) << 32);
#endif
}
inline Int64 ByteOrder::flipBytes(Int64 value)
{
return Int64(flipBytes(UInt64(value)));
}
#endif // POCO_HAVE_INT64
//
// some macro trickery to automate the method implementation
//
#define POCO_IMPLEMENT_BYTEORDER_NOOP_(op, type) \
inline type ByteOrder::op(type value) \
{ \
return value; \
}
#define POCO_IMPLEMENT_BYTEORDER_FLIP_(op, type) \
inline type ByteOrder::op(type value) \
{ \
return flipBytes(value); \
}
#if defined(POCO_HAVE_INT64)
#define POCO_IMPLEMENT_BYTEORDER_NOOP(op) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int16) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt16) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int32) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt32) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int64) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt64)
#define POCO_IMPLEMENT_BYTEORDER_FLIP(op) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int16) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt16) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int32) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt32) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int64) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt64)
#else
#define POCO_IMPLEMENT_BYTEORDER_NOOP(op) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int16) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt16) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int32) \
POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt32)
#define POCO_IMPLEMENT_BYTEORDER_FLIP(op) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int16) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt16) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int32) \
POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt32)
#endif
#if defined(POCO_ARCH_BIG_ENDIAN)
#define POCO_IMPLEMENT_BYTEORDER_BIG POCO_IMPLEMENT_BYTEORDER_NOOP
#define POCO_IMPLEMENT_BYTEORDER_LIT POCO_IMPLEMENT_BYTEORDER_FLIP
#else
#define POCO_IMPLEMENT_BYTEORDER_BIG POCO_IMPLEMENT_BYTEORDER_FLIP
#define POCO_IMPLEMENT_BYTEORDER_LIT POCO_IMPLEMENT_BYTEORDER_NOOP
#endif
POCO_IMPLEMENT_BYTEORDER_BIG(toBigEndian)
POCO_IMPLEMENT_BYTEORDER_BIG(fromBigEndian)
POCO_IMPLEMENT_BYTEORDER_BIG(toNetwork)
POCO_IMPLEMENT_BYTEORDER_BIG(fromNetwork)
POCO_IMPLEMENT_BYTEORDER_LIT(toLittleEndian)
POCO_IMPLEMENT_BYTEORDER_LIT(fromLittleEndian)
} // namespace Poco
#endif // Foundation_ByteOrder_INCLUDED

View File

@ -0,0 +1,81 @@
//
// Channel.h
//
// Library: Foundation
// Package: Logging
// Module: Channel
//
// Definition of the Channel class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Channel_INCLUDED
#define Foundation_Channel_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Configurable.h"
#include "Poco/Mutex.h"
#include "Poco/RefCountedObject.h"
#include "Poco/AutoPtr.h"
namespace Poco {
class Message;
class Foundation_API Channel: public Configurable, public RefCountedObject
/// The base class for all Channel classes.
///
/// Supports reference counting based garbage
/// collection and provides trivial implementations
/// of getProperty() and setProperty().
{
public:
using Ptr = AutoPtr<Channel>;
Channel();
/// Creates the channel and initializes
/// the reference count to one.
virtual void open();
/// Does whatever is necessary to open the channel.
/// The default implementation does nothing.
virtual void close();
/// Does whatever is necessary to close the channel.
/// The default implementation does nothing.
virtual void log(const Message& msg) = 0;
/// Logs the given message to the channel. Must be
/// overridden by subclasses.
///
/// If the channel has not been opened yet, the log()
/// method will open it.
void setProperty(const std::string& name, const std::string& value);
/// Throws a PropertyNotSupportedException.
std::string getProperty(const std::string& name) const;
/// Throws a PropertyNotSupportedException.
protected:
virtual ~Channel();
private:
Channel(const Channel&);
Channel& operator = (const Channel&);
};
} // namespace Poco
#endif // Foundation_Channel_INCLUDED

View File

@ -0,0 +1,108 @@
//
// Checksum.h
//
// Library: Foundation
// Package: Core
// Module: Checksum
//
// Definition of the Checksum class.
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Checksum_INCLUDED
#define Foundation_Checksum_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API Checksum
/// This class calculates CRC-32 or Adler-32 checksums
/// for arbitrary data.
///
/// A cyclic redundancy check (CRC) is a type of hash function, which is used to produce a
/// small, fixed-size checksum of a larger block of data, such as a packet of network
/// traffic or a computer file. CRC-32 is one of the most commonly used CRC algorithms.
///
/// Adler-32 is a checksum algorithm which was invented by Mark Adler.
/// It is almost as reliable as a 32-bit cyclic redundancy check for protecting against
/// accidental modification of data, such as distortions occurring during a transmission,
/// but is significantly faster to calculate in software.
{
public:
enum Type
{
TYPE_ADLER32 = 0,
TYPE_CRC32
};
Checksum();
/// Creates a CRC-32 checksum initialized to 0.
Checksum(Type t);
/// Creates the Checksum, using the given type.
~Checksum();
/// Destroys the Checksum.
void update(const char* data, unsigned length);
/// Updates the checksum with the given data.
void update(const std::string& data);
/// Updates the checksum with the given data.
void update(char data);
/// Updates the checksum with the given data.
Poco::UInt32 checksum() const;
/// Returns the calculated checksum.
Type type() const;
/// Which type of checksum are we calulcating
private:
Type _type;
Poco::UInt32 _value;
};
//
// inlines
//
inline void Checksum::update(const std::string& data)
{
update(data.c_str(), static_cast<unsigned int>(data.size()));
}
inline void Checksum::update(char c)
{
update(&c, 1);
}
inline Poco::UInt32 Checksum::checksum() const
{
return _value;
}
inline Checksum::Type Checksum::type() const
{
return _type;
}
} // namespace Poco
#endif // Foundation_Checksum_INCLUDED

View File

@ -0,0 +1,107 @@
//
// ClassLibrary.h
//
// Library: Foundation
// Package: SharedLibrary
// Module: ClassLoader
//
// Definitions for class libraries.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ClassLibrary_INCLUDED
#define Foundation_ClassLibrary_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Manifest.h"
#include <typeinfo>
#if defined(_WIN32)
#define POCO_LIBRARY_API __declspec(dllexport)
#elif defined(__GNUC__) && (__GNUC__ >= 4)
#define POCO_LIBRARY_API __attribute__ ((visibility ("default")))
#else
#define POCO_LIBRARY_API
#endif
//
// the entry points for every class library
//
extern "C"
{
bool POCO_LIBRARY_API pocoBuildManifest(Poco::ManifestBase* pManifest);
void POCO_LIBRARY_API pocoInitializeLibrary();
void POCO_LIBRARY_API pocoUninitializeLibrary();
}
//
// additional support for named manifests
//
#define POCO_DECLARE_NAMED_MANIFEST(name) \
extern "C" \
{ \
bool POCO_LIBRARY_API POCO_JOIN(pocoBuildManifest, name)(Poco::ManifestBase* pManifest); \
}
//
// Macros to automatically implement pocoBuildManifest
//
// usage:
//
// POCO_BEGIN_MANIFEST(MyBaseClass)
// POCO_EXPORT_CLASS(MyFirstClass)
// POCO_EXPORT_CLASS(MySecondClass)
// ...
// POCO_END_MANIFEST
//
#define POCO_BEGIN_MANIFEST_IMPL(fnName, base) \
bool fnName(Poco::ManifestBase* pManifest_) \
{ \
typedef base _Base; \
typedef Poco::Manifest<_Base> _Manifest; \
std::string requiredType(typeid(_Manifest).name()); \
std::string actualType(pManifest_->className()); \
if (requiredType == actualType) \
{ \
Poco::Manifest<_Base>* pManifest = static_cast<_Manifest*>(pManifest_);
#define POCO_BEGIN_MANIFEST(base) \
POCO_BEGIN_MANIFEST_IMPL(pocoBuildManifest, base)
#define POCO_BEGIN_NAMED_MANIFEST(name, base) \
POCO_DECLARE_NAMED_MANIFEST(name) \
POCO_BEGIN_MANIFEST_IMPL(POCO_JOIN(pocoBuildManifest, name), base)
#define POCO_END_MANIFEST \
return true; \
} \
else return false; \
}
#define POCO_EXPORT_CLASS(cls) \
pManifest->insert(new Poco::MetaObject<cls, _Base>(#cls));
#define POCO_EXPORT_INTERFACE(cls, itf) \
pManifest->insert(new Poco::MetaObject<cls, _Base>(itf));
#define POCO_EXPORT_SINGLETON(cls) \
pManifest->insert(new Poco::MetaSingleton<cls, _Base>(#cls));
#endif // Foundation_ClassLibrary_INCLUDED

View File

@ -0,0 +1,365 @@
//
// ClassLoader.h
//
// Library: Foundation
// Package: SharedLibrary
// Module: ClassLoader
//
// Definition of the ClassLoader class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ClassLoader_INCLUDED
#define Foundation_ClassLoader_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/MetaObject.h"
#include "Poco/Manifest.h"
#include "Poco/SharedLibrary.h"
#include "Poco/Mutex.h"
#include "Poco/Exception.h"
#include <map>
namespace Poco {
template <class Base>
class ClassLoader
/// The ClassLoader loads C++ classes from shared libraries
/// at runtime. It must be instantiated with a root class
/// of the loadable classes.
/// For a class to be loadable from a library, the library
/// must provide a Manifest of all the classes it contains.
/// The Manifest for a shared library can be easily built
/// with the help of the macros in the header file
/// "Foundation/ClassLibrary.h".
///
/// Starting with POCO release 1.3, a class library can
/// export multiple manifests. In addition to the default
/// (unnamed) manifest, multiple named manifests can
/// be exported, each having a different base class.
///
/// There is one important restriction: one instance of
/// ClassLoader can only load one manifest from a class
/// library.
{
public:
typedef AbstractMetaObject<Base> Meta;
typedef Manifest<Base> Manif;
typedef void (*InitializeLibraryFunc)();
typedef void (*UninitializeLibraryFunc)();
typedef bool (*BuildManifestFunc)(ManifestBase*);
struct LibraryInfo
{
SharedLibrary* pLibrary;
const Manif* pManifest;
int refCount;
};
typedef std::map<std::string, LibraryInfo> LibraryMap;
class Iterator
/// The ClassLoader's very own iterator class.
{
public:
typedef std::pair<std::string, const Manif*> Pair;
Iterator(const typename LibraryMap::const_iterator& it)
{
_it = it;
}
Iterator(const Iterator& it)
{
_it = it._it;
}
~Iterator()
{
}
Iterator& operator = (const Iterator& it)
{
_it = it._it;
return *this;
}
inline bool operator == (const Iterator& it) const
{
return _it == it._it;
}
inline bool operator != (const Iterator& it) const
{
return _it != it._it;
}
Iterator& operator ++ () // prefix
{
++_it;
return *this;
}
Iterator operator ++ (int) // postfix
{
Iterator result(_it);
++_it;
return result;
}
inline const Pair* operator * () const
{
_pair.first = _it->first;
_pair.second = _it->second.pManifest;
return &_pair;
}
inline const Pair* operator -> () const
{
_pair.first = _it->first;
_pair.second = _it->second.pManifest;
return &_pair;
}
private:
typename LibraryMap::const_iterator _it;
mutable Pair _pair;
};
ClassLoader()
/// Creates the ClassLoader.
{
}
virtual ~ClassLoader()
/// Destroys the ClassLoader.
{
for (auto& p: _map)
{
delete p.second.pLibrary;
delete p.second.pManifest;
}
}
void loadLibrary(const std::string& path, const std::string& manifest)
/// Loads a library from the given path, using the given manifest.
/// Does nothing if the library is already loaded.
/// Throws a LibraryLoadException if the library
/// cannot be loaded or does not have a Manifest.
/// If the library exports a function named "pocoInitializeLibrary",
/// this function is executed.
/// If called multiple times for the same library,
/// the number of calls to unloadLibrary() must be the same
/// for the library to become unloaded.
{
FastMutex::ScopedLock lock(_mutex);
typename LibraryMap::iterator it = _map.find(path);
if (it == _map.end())
{
LibraryInfo li;
li.pLibrary = 0;
li.pManifest = 0;
li.refCount = 1;
try
{
li.pLibrary = new SharedLibrary(path);
li.pManifest = new Manif();
std::string pocoBuildManifestSymbol("pocoBuildManifest");
pocoBuildManifestSymbol.append(manifest);
if (li.pLibrary->hasSymbol("pocoInitializeLibrary"))
{
InitializeLibraryFunc initializeLibrary = (InitializeLibraryFunc) li.pLibrary->getSymbol("pocoInitializeLibrary");
initializeLibrary();
}
if (li.pLibrary->hasSymbol(pocoBuildManifestSymbol))
{
BuildManifestFunc buildManifest = (BuildManifestFunc) li.pLibrary->getSymbol(pocoBuildManifestSymbol);
if (buildManifest(const_cast<Manif*>(li.pManifest)))
_map[path] = li;
else
throw LibraryLoadException(std::string("Manifest class mismatch in ") + path, manifest);
}
else throw LibraryLoadException(std::string("No manifest in ") + path, manifest);
}
catch (...)
{
delete li.pLibrary;
delete li.pManifest;
throw;
}
}
else
{
++it->second.refCount;
}
}
void loadLibrary(const std::string& path)
/// Loads a library from the given path. Does nothing
/// if the library is already loaded.
/// Throws a LibraryLoadException if the library
/// cannot be loaded or does not have a Manifest.
/// If the library exports a function named "pocoInitializeLibrary",
/// this function is executed.
/// If called multiple times for the same library,
/// the number of calls to unloadLibrary() must be the same
/// for the library to become unloaded.
///
/// Equivalent to loadLibrary(path, "").
{
loadLibrary(path, "");
}
void unloadLibrary(const std::string& path)
/// Unloads the given library.
/// Be extremely cautious when unloading shared libraries.
/// If objects from the library are still referenced somewhere,
/// a total crash is very likely.
/// If the library exports a function named "pocoUninitializeLibrary",
/// this function is executed before it is unloaded.
/// If loadLibrary() has been called multiple times for the same
/// library, the number of calls to unloadLibrary() must be the same
/// for the library to become unloaded.
{
FastMutex::ScopedLock lock(_mutex);
typename LibraryMap::iterator it = _map.find(path);
if (it != _map.end())
{
if (--it->second.refCount == 0)
{
if (it->second.pLibrary->hasSymbol("pocoUninitializeLibrary"))
{
UninitializeLibraryFunc uninitializeLibrary = (UninitializeLibraryFunc) it->second.pLibrary->getSymbol("pocoUninitializeLibrary");
uninitializeLibrary();
}
delete it->second.pManifest;
it->second.pLibrary->unload();
delete it->second.pLibrary;
_map.erase(it);
}
}
else throw NotFoundException(path);
}
const Meta* findClass(const std::string& className) const
/// Returns a pointer to the MetaObject for the given
/// class, or a null pointer if the class is not known.
{
FastMutex::ScopedLock lock(_mutex);
for (const auto& p: _map)
{
const Manif* pManif = p.second.pManifest;
typename Manif::Iterator itm = pManif->find(className);
if (itm != pManif->end())
return *itm;
}
return 0;
}
const Meta& classFor(const std::string& className) const
/// Returns a reference to the MetaObject for the given
/// class. Throws a NotFoundException if the class
/// is not known.
{
const Meta* pMeta = findClass(className);
if (pMeta)
return *pMeta;
else
throw NotFoundException(className);
}
Base* create(const std::string& className) const
/// Creates an instance of the given class.
/// Throws a NotFoundException if the class
/// is not known.
{
return classFor(className).create();
}
Base& instance(const std::string& className) const
/// Returns a reference to the sole instance of
/// the given class. The class must be a singleton,
/// otherwise an InvalidAccessException will be thrown.
/// Throws a NotFoundException if the class
/// is not known.
{
return classFor(className).instance();
}
bool canCreate(const std::string& className) const
/// Returns true if create() can create new instances
/// of the class.
{
return classFor(className).canCreate();
}
void destroy(const std::string& className, Base* pObject) const
/// Destroys the object pObject points to.
/// Does nothing if object is not found.
{
classFor(className).destroy(pObject);
}
bool isAutoDelete(const std::string& className, Base* pObject) const
/// Returns true if the object is automatically
/// deleted by its meta object.
{
return classFor(className).isAutoDelete(pObject);
}
const Manif* findManifest(const std::string& path) const
/// Returns a pointer to the Manifest for the given
/// library, or a null pointer if the library has not been loaded.
{
FastMutex::ScopedLock lock(_mutex);
typename LibraryMap::const_iterator it = _map.find(path);
if (it != _map.end())
return it->second.pManifest;
else
return 0;
}
const Manif& manifestFor(const std::string& path) const
/// Returns a reference to the Manifest for the given library
/// Throws a NotFoundException if the library has not been loaded.
{
const Manif* pManif = findManifest(path);
if (pManif)
return *pManif;
else
throw NotFoundException(path);
}
bool isLibraryLoaded(const std::string& path) const
/// Returns true if the library with the given name
/// has already been loaded.
{
return findManifest(path) != 0;
}
Iterator begin() const
{
FastMutex::ScopedLock lock(_mutex);
return Iterator(_map.begin());
}
Iterator end() const
{
FastMutex::ScopedLock lock(_mutex);
return Iterator(_map.end());
}
private:
LibraryMap _map;
mutable FastMutex _mutex;
};
} // namespace Poco
#endif // Foundation_ClassLoader_INCLUDED

View File

@ -0,0 +1,238 @@
//
// Clock.h
//
// Library: Foundation
// Package: DateTime
// Module: Clock
//
// Definition of the Clock class.
//
// Copyright (c) 2013, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Clock_INCLUDED
#define Foundation_Clock_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API Clock
/// A Clock stores a monotonic* clock value
/// with (theoretical) microseconds resolution.
/// Clocks can be compared with each other
/// and simple arithmetic is supported.
///
/// [*] Note that Clock values are only monotonic if
/// the operating system provides a monotonic clock.
/// The monotonic() function can be used to check whether
/// the system's clock is monotonic.
///
/// Monotonic Clock is available on Windows, Linux, OS X
/// and on POSIX platforms supporting clock_gettime() with CLOCK_MONOTONIC.
///
/// Clock values are relative to a system-dependent epoch time
/// (usually the system's startup time) and have no relation
/// to the time of day.
{
public:
typedef Int64 ClockVal;
/// Monotonic clock value in microsecond resolution.
typedef Int64 ClockDiff;
/// Difference between two ClockVal values in microseconds.
static const ClockVal CLOCKVAL_MIN; /// Minimum clock value.
static const ClockVal CLOCKVAL_MAX; /// Maximum clock value.
Clock();
/// Creates a Clock with the current system clock value.
Clock(ClockVal tv);
/// Creates a Clock from the given clock value.
Clock(const Clock& other);
/// Copy constructor.
~Clock();
/// Destroys the Clock.
Clock& operator = (const Clock& other);
Clock& operator = (ClockVal tv);
void swap(Clock& clock);
/// Swaps the Clock with another one.
void update();
/// Updates the Clock with the current system clock.
bool operator == (const Clock& ts) const;
bool operator != (const Clock& ts) const;
bool operator > (const Clock& ts) const;
bool operator >= (const Clock& ts) const;
bool operator < (const Clock& ts) const;
bool operator <= (const Clock& ts) const;
Clock operator + (ClockDiff d) const;
Clock operator - (ClockDiff d) const;
ClockDiff operator - (const Clock& ts) const;
Clock& operator += (ClockDiff d);
Clock& operator -= (ClockDiff d);
ClockVal microseconds() const;
/// Returns the clock value expressed in microseconds
/// since the system-specific epoch time (usually system
/// startup).
ClockVal raw() const;
/// Returns the clock value expressed in microseconds
/// since the system-specific epoch time (usually system
/// startup).
///
/// Same as microseconds().
ClockDiff elapsed() const;
/// Returns the time elapsed since the time denoted by
/// the Clock instance. Equivalent to Clock() - *this.
bool isElapsed(ClockDiff interval) const;
/// Returns true iff the given interval has passed
/// since the time denoted by the Clock instance.
static ClockDiff resolution();
/// Returns the resolution in units per second.
/// Since the Clock class has microsecond resolution,
/// the returned value is always 1000000.
static ClockDiff accuracy();
/// Returns the system's clock accuracy in microseconds.
static bool monotonic();
/// Returns true iff the system's clock is monotonic.
private:
ClockVal _clock;
};
//
// inlines
//
inline bool Clock::operator == (const Clock& ts) const
{
return _clock == ts._clock;
}
inline bool Clock::operator != (const Clock& ts) const
{
return _clock != ts._clock;
}
inline bool Clock::operator > (const Clock& ts) const
{
return _clock > ts._clock;
}
inline bool Clock::operator >= (const Clock& ts) const
{
return _clock >= ts._clock;
}
inline bool Clock::operator < (const Clock& ts) const
{
return _clock < ts._clock;
}
inline bool Clock::operator <= (const Clock& ts) const
{
return _clock <= ts._clock;
}
inline Clock Clock::operator + (Clock::ClockDiff d) const
{
return Clock(_clock + d);
}
inline Clock Clock::operator - (Clock::ClockDiff d) const
{
return Clock(_clock - d);
}
inline Clock::ClockDiff Clock::operator - (const Clock& ts) const
{
return _clock - ts._clock;
}
inline Clock& Clock::operator += (Clock::ClockDiff d)
{
_clock += d;
return *this;
}
inline Clock& Clock::operator -= (Clock::ClockDiff d)
{
_clock -= d;
return *this;
}
inline Clock::ClockVal Clock::microseconds() const
{
return _clock;
}
inline Clock::ClockDiff Clock::elapsed() const
{
Clock now;
return now - *this;
}
inline bool Clock::isElapsed(Clock::ClockDiff interval) const
{
Clock now;
Clock::ClockDiff diff = now - *this;
return diff >= interval;
}
inline Clock::ClockDiff Clock::resolution()
{
return 1000000;
}
inline void swap(Clock& s1, Clock& s2)
{
s1.swap(s2);
}
inline Clock::ClockVal Clock::raw() const
{
return _clock;
}
} // namespace Poco
#endif // Foundation_Clock_INCLUDED

View File

@ -0,0 +1,137 @@
//
// Condition.h
//
// Library: Foundation
// Package: Threading
// Module: Condition
//
// Definition of the Condition class template.
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Condition_INCLUDED
#define Foundation_Condition_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Mutex.h"
#include "Poco/ScopedUnlock.h"
#include "Poco/Event.h"
#include "Poco/Exception.h"
#include <deque>
namespace Poco {
class Foundation_API Condition
/// A Condition is a synchronization object used to block a thread
/// until a particular condition is met.
/// A Condition object is always used in conjunction with
/// a Mutex (or FastMutex) object.
///
/// Condition objects are similar to POSIX condition variables, which the
/// difference that Condition is not subject to spurious wakeups.
///
/// Threads waiting on a Condition are resumed in FIFO order.
{
public:
Condition();
/// Creates the Condition.
~Condition();
/// Destroys the Condition.
template <class Mtx>
void wait(Mtx& mutex)
/// Unlocks the mutex (which must be locked upon calling
/// wait()) and waits until the Condition is signalled.
///
/// The given mutex will be locked again upon
/// leaving the function, even in case of an exception.
{
ScopedUnlock<Mtx> unlock(mutex, false);
Event event;
{
FastMutex::ScopedLock lock(_mutex);
mutex.unlock();
enqueue(event);
}
event.wait();
}
template <class Mtx>
void wait(Mtx& mutex, long milliseconds)
/// Unlocks the mutex (which must be locked upon calling
/// wait()) and waits for the given time until the Condition is signalled.
///
/// The given mutex will be locked again upon successfully leaving the
/// function, even in case of an exception.
///
/// Throws a TimeoutException if the Condition is not signalled
/// within the given time interval.
{
if (!tryWait(mutex, milliseconds))
throw TimeoutException();
}
template <class Mtx>
bool tryWait(Mtx& mutex, long milliseconds)
/// Unlocks the mutex (which must be locked upon calling
/// tryWait()) and waits for the given time until the Condition is signalled.
///
/// The given mutex will be locked again upon leaving the
/// function, even in case of an exception.
///
/// Returns true if the Condition has been signalled
/// within the given time interval, otherwise false.
{
ScopedUnlock<Mtx> unlock(mutex, false);
Event event;
{
FastMutex::ScopedLock lock(_mutex);
mutex.unlock();
enqueue(event);
}
if (!event.tryWait(milliseconds))
{
FastMutex::ScopedLock lock(_mutex);
dequeue(event);
return false;
}
return true;
}
void signal();
/// Signals the Condition and allows one waiting thread
/// to continue execution.
void broadcast();
/// Signals the Condition and allows all waiting
/// threads to continue their execution.
protected:
void enqueue(Event& event);
void dequeue();
void dequeue(Event& event);
private:
Condition(const Condition&);
Condition& operator = (const Condition&);
typedef std::deque<Event*> WaitQueue;
FastMutex _mutex;
WaitQueue _waitQueue;
};
} // namespace Poco
#endif // Foundation_Condition_INCLUDED

View File

@ -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 <locale> 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 <https://github.com/pocoproject/openssl/blob/master/README.md>
// 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 <http://slproweb.com/products/Win32OpenSSL.html>
// 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

View File

@ -0,0 +1,70 @@
//
// Configurable.h
//
// Library: Foundation
// Package: Logging
// Module: Configurable
//
// Definition of the Configurable class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Configurable_INCLUDED
#define Foundation_Configurable_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API Configurable
/// A simple interface that defines
/// getProperty() and setProperty() methods.
///
/// This interface is implemented by Formatter and
/// Channel and is used to configure arbitrary
/// channels and formatters.
///
/// A property is basically a name-value pair. For
/// simplicity, both names and values are strings.
/// Every property controls a certain aspect of a
/// Formatter or Channel. For example, the PatternFormatter's
/// formatting pattern is set via a property.
///
/// NOTE: The following property names are use internally
/// by the logging framework and must not be used by
/// channels or formatters:
/// - class
/// - pattern (Channel)
/// - formatter (Channel)
{
public:
Configurable();
/// Creates the Configurable.
virtual ~Configurable();
/// Destroys the Configurable.
virtual void setProperty(const std::string& name, const std::string& value) = 0;
/// Sets the property with the given name to the given value.
/// If a property with the given name is not supported, a
/// PropertyNotSupportedException is thrown.
virtual std::string getProperty(const std::string& name) const = 0;
/// Returns the value of the property with the given name.
/// If a property with the given name is not supported, a
/// PropertyNotSupportedException is thrown.
};
} // namespace Poco
#endif // Foundation_Configurable_INCLUDED

View File

@ -0,0 +1,189 @@
//
// ConsoleChannel.h
//
// Library: Foundation
// Package: Logging
// Module: ConsoleChannel
//
// Definition of the ConsoleChannel class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ConsoleChannel_INCLUDED
#define Foundation_ConsoleChannel_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Channel.h"
#include "Poco/Mutex.h"
#include <ostream>
namespace Poco {
class Foundation_API ConsoleChannel: public Channel
/// A channel that writes to an ostream.
///
/// Only the message's text is written, followed
/// by a newline.
///
/// Chain this channel to a FormattingChannel with an
/// appropriate Formatter to control what is contained
/// in the text.
///
/// Similar to StreamChannel, except that a static
/// mutex is used to protect against multiple
/// console channels concurrently writing to the
/// same stream.
{
public:
using Ptr = AutoPtr<ConsoleChannel>;
ConsoleChannel();
/// Creates the channel and attaches std::clog.
ConsoleChannel(std::ostream& str);
/// Creates the channel using the given stream.
void log(const Message& msg);
/// Logs the given message to the channel's stream.
protected:
~ConsoleChannel();
private:
std::ostream& _str;
static FastMutex _mutex;
};
class Foundation_API ColorConsoleChannel: public Channel
/// A channel that writes to an ostream.
///
/// Only the message's text is written, followed
/// by a newline.
///
/// Messages can be colored depending on priority.
/// The console device must support ANSI escape codes
/// in order to display colored messages.
///
/// To enable message coloring, set the "enableColors"
/// property to true (default). Furthermore, colors can be
/// configured by setting the following properties
/// (default values are given in parenthesis):
///
/// * traceColor (gray)
/// * debugColor (gray)
/// * informationColor (default)
/// * noticeColor (default)
/// * warningColor (yellow)
/// * errorColor (lightRed)
/// * criticalColor (lightRed)
/// * fatalColor (lightRed)
///
/// The following color values are supported:
///
/// * default
/// * black
/// * red
/// * green
/// * brown
/// * blue
/// * magenta
/// * cyan
/// * gray
/// * darkgray
/// * lightRed
/// * lightGreen
/// * yellow
/// * lightBlue
/// * lightMagenta
/// * lightCyan
/// * white
///
/// Chain this channel to a FormattingChannel with an
/// appropriate Formatter to control what is contained
/// in the text.
///
/// Similar to StreamChannel, except that a static
/// mutex is used to protect against multiple
/// console channels concurrently writing to the
/// same stream.
{
public:
ColorConsoleChannel();
/// Creates the channel and attaches std::clog.
ColorConsoleChannel(std::ostream& str);
/// Creates the channel using the given stream.
void log(const Message& msg);
/// Logs the given message to the channel's stream.
void setProperty(const std::string& name, const std::string& value);
/// Sets the property with the given name.
///
/// The following properties are supported:
/// * enableColors: Enable or disable colors.
/// * traceColor: Specify color for trace messages.
/// * debugColor: Specify color for debug messages.
/// * informationColor: Specify color for information messages.
/// * noticeColor: Specify color for notice messages.
/// * warningColor: Specify color for warning messages.
/// * errorColor: Specify color for error messages.
/// * criticalColor: Specify color for critical messages.
/// * fatalColor: Specify color for fatal messages.
///
/// See the class documentation for a list of supported color values.
std::string getProperty(const std::string& name) const;
/// Returns the value of the property with the given name.
/// See setProperty() for a description of the supported
/// properties.
protected:
enum Color
{
CC_DEFAULT = 0x0027,
CC_BLACK = 0x001e,
CC_RED = 0x001f,
CC_GREEN = 0x0020,
CC_BROWN = 0x0021,
CC_BLUE = 0x0022,
CC_MAGENTA = 0x0023,
CC_CYAN = 0x0024,
CC_GRAY = 0x0025,
CC_DARKGRAY = 0x011e,
CC_LIGHTRED = 0x011f,
CC_LIGHTGREEN = 0x0120,
CC_YELLOW = 0x0121,
CC_LIGHTBLUE = 0x0122,
CC_LIGHTMAGENTA = 0x0123,
CC_LIGHTCYAN = 0x0124,
CC_WHITE = 0x0125
};
~ColorConsoleChannel();
Color parseColor(const std::string& color) const;
std::string formatColor(Color color) const;
void initColors();
private:
std::ostream& _str;
bool _enableColors;
Color _colors[9];
static FastMutex _mutex;
static const std::string CSI;
};
} // namespace Poco
#endif // Foundation_ConsoleChannel_INCLUDED

View File

@ -0,0 +1,237 @@
//
// CountingStream.h
//
// Library: Foundation
// Package: Streams
// Module: CountingStream
//
// Definition of the CountingStreamBuf, CountingInputStream and CountingOutputStream classes.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_CountingStream_INCLUDED
#define Foundation_CountingStream_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/UnbufferedStreamBuf.h"
#include <istream>
#include <ostream>
namespace Poco {
class Foundation_API CountingStreamBuf: public UnbufferedStreamBuf
/// This stream buffer counts all characters and lines
/// going through it.
{
public:
CountingStreamBuf();
/// Creates an unconnected CountingStreamBuf.
CountingStreamBuf(std::istream& istr);
/// Creates the CountingStreamBuf and connects it
/// to the given input stream.
CountingStreamBuf(std::ostream& ostr);
/// Creates the CountingStreamBuf and connects it
/// to the given output stream.
~CountingStreamBuf();
/// Destroys the CountingStream.
std::streamsize chars() const;
/// Returns the total number of characters.
std::streamsize lines() const;
/// Returns the total number of lines.
std::streamsize pos() const;
/// Returns the number of characters on the current line.
void reset();
/// Resets all counters.
void setCurrentLineNumber(std::streamsize line);
/// Sets the current line number.
///
/// This is mainly useful when parsing C/C++
/// preprocessed source code containing #line directives.
std::streamsize getCurrentLineNumber() const;
/// Returns the current line number (same as lines()).
void addChars(std::streamsize chars);
/// Add to the total number of characters.
void addLines(std::streamsize lines);
/// Add to the total number of lines.
void addPos(std::streamsize pos);
/// Add to the number of characters on the current line.
protected:
int readFromDevice();
int writeToDevice(char c);
private:
std::istream* _pIstr;
std::ostream* _pOstr;
std::streamsize _chars;
std::streamsize _lines;
std::streamsize _pos;
};
class Foundation_API CountingIOS: public virtual std::ios
/// The base class for CountingInputStream and CountingOutputStream.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
CountingIOS();
/// Creates the basic stream and leaves it unconnected.
CountingIOS(std::istream& istr);
/// Creates the basic stream and connects it
/// to the given input stream.
CountingIOS(std::ostream& ostr);
/// Creates the basic stream and connects it
/// to the given output stream.
~CountingIOS();
/// Destroys the stream.
std::streamsize chars() const;
/// Returns the total number of characters.
std::streamsize lines() const;
/// Returns the total number of lines.
std::streamsize pos() const;
/// Returns the number of characters on the current line.
void reset();
/// Resets all counters.
void setCurrentLineNumber(std::streamsize line);
/// Sets the current line number.
///
/// This is mainly useful when parsing C/C++
/// preprocessed source code containing #line directives.
std::streamsize getCurrentLineNumber() const;
/// Returns the current line number (same as lines()).
void addChars(std::streamsize chars);
/// Add to the total number of characters.
void addLines(std::streamsize lines);
/// Add to the total number of lines.
void addPos(std::streamsize pos);
/// Add to the number of characters on the current line.
CountingStreamBuf* rdbuf();
/// Returns a pointer to the underlying streambuf.
protected:
CountingStreamBuf _buf;
};
class Foundation_API CountingInputStream: public CountingIOS, public std::istream
/// This stream counts all characters and lines
/// going through it. This is useful for lexers and parsers
/// that need to determine the current position in the stream.
{
public:
CountingInputStream(std::istream& istr);
/// Creates the CountingInputStream and connects it
/// to the given input stream.
~CountingInputStream();
/// Destroys the stream.
};
class Foundation_API CountingOutputStream: public CountingIOS, public std::ostream
/// This stream counts all characters and lines
/// going through it.
{
public:
CountingOutputStream();
/// Creates an unconnected CountingOutputStream.
CountingOutputStream(std::ostream& ostr);
/// Creates the CountingOutputStream and connects it
/// to the given output stream.
~CountingOutputStream();
/// Destroys the CountingOutputStream.
};
//
// inlines
//
inline std::streamsize CountingStreamBuf::chars() const
{
return _chars;
}
inline std::streamsize CountingStreamBuf::lines() const
{
return _lines;
}
inline std::streamsize CountingStreamBuf::pos() const
{
return _pos;
}
inline std::streamsize CountingStreamBuf::getCurrentLineNumber() const
{
return _lines;
}
inline std::streamsize CountingIOS::chars() const
{
return _buf.chars();
}
inline std::streamsize CountingIOS::lines() const
{
return _buf.lines();
}
inline std::streamsize CountingIOS::pos() const
{
return _buf.pos();
}
inline std::streamsize CountingIOS::getCurrentLineNumber() const
{
return _buf.getCurrentLineNumber();
}
} // namespace Poco
#endif // Foundation_CountingStream_INCLUDED

View File

@ -0,0 +1,78 @@
//
// DataURIStream.h
//
// Library: Foundation
// Package: Streams
// Module: DataURIStreamFactory
//
// Definition of the DataURIStream class.
//
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DataURIStream_INCLUDED
#define Foundation_DataURIStream_INCLUDED
#include "Poco/Foundation.h"
#include <istream>
#include <memory>
namespace Poco {
class Base64Decoder;
class MemoryInputStream;
class URI;
class Foundation_API DataURIStreamIOS: public virtual std::ios
/// The base class for DataURIStream.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
DataURIStreamIOS(const URI& uri);
~DataURIStreamIOS();
std::streambuf* rdbuf();
protected:
std::streambuf* _buf;
private:
DataURIStreamIOS(const DataURIStreamIOS&);
DataURIStreamIOS& operator = (const DataURIStreamIOS&);
std::string _data;
std::unique_ptr<MemoryInputStream> _memoryStream;
std::unique_ptr<Base64Decoder> _base64Decoder;
};
class Foundation_API DataURIStream: public DataURIStreamIOS, public std::istream
/// An input stream for reading data from a data URI.
/// For example, when constructed from "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D" it reads "Hello, World!".
{
public:
DataURIStream(const URI& uri);
/// Creates a DataURIStream for the given data URI,
/// ready for reading data.
/// Throws a DataFormatException exception if the data is incorrect format.
~DataURIStream();
/// Destroys the DataURIStream.
private:
DataURIStream(const DataURIStream&);
DataURIStream& operator = (const DataURIStream&);
};
} // namespace Poco
#endif // Foundation_DataURIStream_INCLUDED

View File

@ -0,0 +1,58 @@
//
// DataURIStreamFactory.h
//
// Library: Foundation
// Package: URI
// Module: DataURIStreamFactory
//
// Definition of the DataURIStreamFactory class.
//
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DataURIStreamFactory_INCLUDED
#define Foundation_DataURIStreamFactory_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/URIStreamFactory.h"
namespace Poco {
class Foundation_API DataURIStreamFactory: public URIStreamFactory
/// An implementation of the URIStreamFactory interface
/// that read data from data URIs.
/// For example, for URI "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D" it read "Hello, World!".
{
public:
DataURIStreamFactory();
/// Creates the DataURIStreamFactory.
~DataURIStreamFactory();
/// Destroys the DataURIStreamFactory.
std::istream* open(const URI& uri);
/// Creates an input stream returning decoded data from the given data URI.
///
/// Throws a DataFormatException exception if the data is incorrect format.
static void registerFactory();
/// Registers the DataURIStreamFactory with the
/// default URIStreamOpener instance.
static void unregisterFactory();
/// Unregisters the DataURIStreamFactory with the
/// default URIStreamOpener instance.
};
} // namespace Poco
#endif // Foundation_DataURIStreamFactory_INCLUDED

View File

@ -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 <http://vsg.cape.com/~pbaum/date/jdimp.htm>, 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 <http://vsg.cape.com/~pbaum/date/injdimp.htm>, 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

View File

@ -0,0 +1,109 @@
//
// DateTimeFormat.h
//
// Library: Foundation
// Package: DateTime
// Module: DateTimeFormat
//
// Definition of the DateTimeFormat class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DateTimeFormat_INCLUDED
#define Foundation_DateTimeFormat_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API DateTimeFormat
/// Definition of date/time formats and various
/// constants used by DateTimeFormatter and DateTimeParser.
{
public:
// predefined date formats
static const std::string ISO8601_FORMAT;
/// The date/time format defined in the ISO 8601 standard.
///
/// Examples:
/// 2005-01-01T12:00:00+01:00
/// 2005-01-01T11:00:00Z
static const std::string ISO8601_FRAC_FORMAT;
/// The date/time format defined in the ISO 8601 standard,
/// with fractional seconds.
///
/// Examples:
/// 2005-01-01T12:00:00.000000+01:00
/// 2005-01-01T11:00:00.000000Z
static const std::string RFC822_FORMAT;
/// The date/time format defined in RFC 822 (obsoleted by RFC 1123).
///
/// Examples:
/// Sat, 1 Jan 05 12:00:00 +0100
/// Sat, 1 Jan 05 11:00:00 GMT
static const std::string RFC1123_FORMAT;
/// The date/time format defined in RFC 1123 (obsoletes RFC 822).
///
/// Examples:
/// Sat, 1 Jan 2005 12:00:00 +0100
/// Sat, 1 Jan 2005 11:00:00 GMT
static const std::string HTTP_FORMAT;
/// The date/time format defined in the HTTP specification (RFC 2616),
/// which is basically a variant of RFC 1036 with a zero-padded day field.
///
/// Examples:
/// Sat, 01 Jan 2005 12:00:00 +0100
/// Sat, 01 Jan 2005 11:00:00 GMT
static const std::string RFC850_FORMAT;
/// The date/time format defined in RFC 850 (obsoleted by RFC 1036).
///
/// Examples:
/// Saturday, 1-Jan-05 12:00:00 +0100
/// Saturday, 1-Jan-05 11:00:00 GMT
static const std::string RFC1036_FORMAT;
/// The date/time format defined in RFC 1036 (obsoletes RFC 850).
///
/// Examples:
/// Saturday, 1 Jan 05 12:00:00 +0100
/// Saturday, 1 Jan 05 11:00:00 GMT
static const std::string ASCTIME_FORMAT;
/// The date/time format produced by the ANSI C asctime() function.
///
/// Example:
/// Sat Jan 1 12:00:00 2005
static const std::string SORTABLE_FORMAT;
/// A simple, sortable date/time format.
///
/// Example:
/// 2005-01-01 12:00:00
// names used by formatter and parser
static const std::string WEEKDAY_NAMES[7];
/// English names of week days (Sunday, Monday, Tuesday, ...).
static const std::string MONTH_NAMES[12];
/// English names of months (January, February, ...).
};
} // namespace Poco
#endif // Foundation_DateTimeFormat_INCLUDED

View File

@ -0,0 +1,215 @@
//
// DateTimeFormatter.h
//
// Library: Foundation
// Package: DateTime
// Module: DateTimeFormatter
//
// Definition of the DateTimeFormatter class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DateTimeFormatter_INCLUDED
#define Foundation_DateTimeFormatter_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/DateTime.h"
#include "Poco/LocalDateTime.h"
namespace Poco {
class Timestamp;
class Timespan;
class Foundation_API DateTimeFormatter
/// This class converts dates and times into strings, supporting a
/// variety of standard and custom formats.
///
/// There are two kind of static member functions:
/// * format* functions return a std::string containing
/// the formatted value.
/// * append* functions append the formatted value to
/// an existing string.
{
public:
enum
{
UTC = 0xFFFF /// Special value for timeZoneDifferential denoting UTC.
};
static std::string format(const Timestamp& timestamp, const std::string& fmt, int timeZoneDifferential = UTC);
/// Formats the given timestamp according to the given format.
/// The format string is used as a template to format the date and
/// is copied character by character except for the following special characters,
/// which are replaced by the corresponding value.
///
/// * %w - abbreviated weekday (Mon, Tue, ...)
/// * %W - full weekday (Monday, Tuesday, ...)
/// * %b - abbreviated month (Jan, Feb, ...)
/// * %B - full month (January, February, ...)
/// * %d - zero-padded day of month (01 .. 31)
/// * %e - day of month (1 .. 31)
/// * %f - space-padded day of month ( 1 .. 31)
/// * %m - zero-padded month (01 .. 12)
/// * %n - month (1 .. 12)
/// * %o - space-padded month ( 1 .. 12)
/// * %y - year without century (70)
/// * %Y - year with century (1970)
/// * %H - hour (00 .. 23)
/// * %h - hour (00 .. 12)
/// * %a - am/pm
/// * %A - AM/PM
/// * %M - minute (00 .. 59)
/// * %S - second (00 .. 59)
/// * %s - seconds and microseconds (equivalent to %S.%F)
/// * %i - millisecond (000 .. 999)
/// * %c - centisecond (0 .. 9)
/// * %F - fractional seconds/microseconds (000000 - 999999)
/// * %z - time zone differential in ISO 8601 format (Z or +NN.NN)
/// * %Z - time zone differential in RFC format (GMT or +NNNN)
/// * %% - percent sign
///
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static std::string format(const DateTime& dateTime, const std::string& fmt, int timeZoneDifferential = UTC);
/// Formats the given date and time according to the given format.
/// See format(const Timestamp&, const std::string&, int) for more information.
static std::string format(const LocalDateTime& dateTime, const std::string& fmt);
/// Formats the given local date and time according to the given format.
/// See format(const Timestamp&, const std::string&, int) for more information.
static std::string format(const Timespan& timespan, const std::string& fmt = "%dd %H:%M:%S.%i");
/// Formats the given timespan according to the given format.
/// The format string is used as a template to format the date and
/// is copied character by character except for the following special characters,
/// which are replaced by the corresponding value.
///
/// * %d - days
/// * %H - hours (00 .. 23)
/// * %h - total hours (0 .. n)
/// * %M - minutes (00 .. 59)
/// * %m - total minutes (0 .. n)
/// * %S - seconds (00 .. 59)
/// * %s - total seconds (0 .. n)
/// * %i - milliseconds (000 .. 999)
/// * %c - centisecond (0 .. 9)
/// * %F - fractional seconds/microseconds (000000 - 999999)
/// * %% - percent sign
static void append(std::string& str, const Timestamp& timestamp, const std::string& fmt, int timeZoneDifferential = UTC);
/// Formats the given timestamp according to the given format and appends it to str.
///
/// See format() for documentation of the formatting string.
static void append(std::string& str, const DateTime& dateTime, const std::string& fmt, int timeZoneDifferential = UTC);
/// Formats the given date and time according to the given format and appends it to str.
///
/// See format() for documentation of the formatting string.
static void append(std::string& str, const LocalDateTime& dateTime, const std::string& fmt);
/// Formats the given local date and time according to the given format and appends it to str.
///
/// See format() for documentation of the formatting string.
static void append(std::string& str, const Timespan& timespan, const std::string& fmt = "%dd %H:%M:%S.%i");
/// Formats the given timespan according to the given format and appends it to str.
///
/// See format() for documentation of the formatting string.
static std::string tzdISO(int timeZoneDifferential);
/// Formats the given timezone differential in ISO format.
/// If timeZoneDifferential is UTC, "Z" is returned,
/// otherwise, +HH.MM (or -HH.MM) is returned.
static std::string tzdRFC(int timeZoneDifferential);
/// Formats the given timezone differential in RFC format.
/// If timeZoneDifferential is UTC, "GMT" is returned,
/// otherwise ++HHMM (or -HHMM) is returned.
static void tzdISO(std::string& str, int timeZoneDifferential);
/// Formats the given timezone differential in ISO format
/// and appends it to the given string.
/// If timeZoneDifferential is UTC, "Z" is returned,
/// otherwise, +HH.MM (or -HH.MM) is returned.
static void tzdRFC(std::string& str, int timeZoneDifferential);
/// Formats the given timezone differential in RFC format
/// and appends it to the given string.
/// If timeZoneDifferential is UTC, "GMT" is returned,
/// otherwise ++HHMM (or -HHMM) is returned.
};
//
// inlines
//
inline std::string DateTimeFormatter::format(const Timestamp& timestamp, const std::string& fmt, int timeZoneDifferential)
{
DateTime dateTime(timestamp);
return format(dateTime, fmt, timeZoneDifferential);
}
inline std::string DateTimeFormatter::format(const DateTime& dateTime, const std::string& fmt, int timeZoneDifferential)
{
std::string result;
result.reserve(64);
append(result, dateTime, fmt, timeZoneDifferential);
return result;
}
inline std::string DateTimeFormatter::format(const LocalDateTime& dateTime, const std::string& fmt)
{
return format(dateTime._dateTime, fmt, dateTime._tzd);
}
inline std::string DateTimeFormatter::format(const Timespan& timespan, const std::string& fmt)
{
std::string result;
result.reserve(32);
append(result, timespan, fmt);
return result;
}
inline void DateTimeFormatter::append(std::string& str, const Timestamp& timestamp, const std::string& fmt, int timeZoneDifferential)
{
DateTime dateTime(timestamp);
append(str, dateTime, fmt, timeZoneDifferential);
}
inline std::string DateTimeFormatter::tzdISO(int timeZoneDifferential)
{
std::string result;
result.reserve(8);
tzdISO(result, timeZoneDifferential);
return result;
}
inline std::string DateTimeFormatter::tzdRFC(int timeZoneDifferential)
{
std::string result;
result.reserve(8);
tzdRFC(result, timeZoneDifferential);
return result;
}
} // namespace Poco
#endif // Foundation_DateTimeFormatter_INCLUDED

View File

@ -0,0 +1,116 @@
//
// DateTimeParser.h
//
// Library: Foundation
// Package: DateTime
// Module: DateTimeParser
//
// Definition of the DateTimeParser class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DateTimeParser_INCLUDED
#define Foundation_DateTimeParser_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/DateTime.h"
namespace Poco {
class Foundation_API DateTimeParser
/// This class provides a method for parsing dates and times
/// from strings. All parsing methods do their best to
/// parse a meaningful result, even from malformed input
/// strings.
///
/// The returned DateTime will always contain a time in the same
/// timezone as the time in the string. Call DateTime::makeUTC()
/// with the timeZoneDifferential returned by parse() to convert
/// the DateTime to UTC.
///
/// Note: When parsing a time in 12-hour (AM/PM) format, the hour
/// (%h) must be parsed before the AM/PM designator (%a, %A),
/// otherwise the AM/PM designator will be ignored.
///
/// See the DateTimeFormatter class for a list of supported format specifiers.
/// In addition to the format specifiers supported by DateTimeFormatter, an
/// additional specifier is supported: %r will parse a year given by either
/// two or four digits. Years 69-00 are interpreted in the 20th century
/// (1969-2000), years 01-68 in the 21th century (2001-2068).
///
/// Note that in the current implementation all characters other than format specifiers in
/// the format string are ignored/not matched against the date/time string. This may
/// lead to non-error results even with nonsense input strings.
/// This may change in a future version to a more strict behavior.
/// If more strict format validation of date/time strings is required, a regular
/// expression could be used for initial validation, before passing the string
/// to DateTimeParser.
{
public:
static void parse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
/// Parses a date and time in the given format from the given string.
/// Throws a SyntaxException if the string cannot be successfully parsed.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static DateTime parse(const std::string& fmt, const std::string& str, int& timeZoneDifferential);
/// Parses a date and time in the given format from the given string.
/// Throws a SyntaxException if the string cannot be successfully parsed.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static bool tryParse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
/// Parses a date and time in the given format from the given string.
/// Returns true if the string has been successfully parsed, false otherwise.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static void parse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
/// Parses a date and time from the given dateTime string. Before parsing, the method
/// examines the dateTime string for a known date/time format.
/// Throws a SyntaxException if the string cannot be successfully parsed.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static DateTime parse(const std::string& str, int& timeZoneDifferential);
/// Parses a date and time from the given dateTime string. Before parsing, the method
/// examines the dateTime string for a known date/time format.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static bool tryParse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
/// Parses a date and time from the given dateTime string. Before parsing, the method
/// examines the dateTime string for a known date/time format.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static int parseMonth(std::string::const_iterator& it, const std::string::const_iterator& end);
/// Tries to interpret the given range as a month name. The range must be at least
/// three characters long.
/// Returns the month number (1 .. 12) if the month name is valid. Otherwise throws
/// a SyntaxException.
static int parseDayOfWeek(std::string::const_iterator& it, const std::string::const_iterator& end);
/// Tries to interpret the given range as a weekday name. The range must be at least
/// three characters long.
/// Returns the weekday number (0 .. 6, where 0 = Sunday, 1 = Monday, etc.) if the
/// weekday name is valid. Otherwise throws a SyntaxException.
protected:
static int parseTZD(std::string::const_iterator& it, const std::string::const_iterator& end);
static int parseAMPM(std::string::const_iterator& it, const std::string::const_iterator& end, int hour);
};
} // namespace Poco
#endif // Foundation_DateTimeParser_INCLUDED

View File

@ -0,0 +1,70 @@
//
// Debugger.h
//
// Library: Foundation
// Package: Core
// Module: Debugger
//
// Definition of the Debugger class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Debugger_INCLUDED
#define Foundation_Debugger_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API Debugger
/// The Debugger class provides an interface to the debugger.
/// The presence of a debugger can be checked for,
/// messages can be written to the debugger's log window
/// and a break into the debugger can be enforced.
/// The methods only work if the program is compiled
/// in debug mode (the macro _DEBUG is defined).
{
public:
static bool isAvailable();
/// Returns true if a debugger is available, false otherwise.
/// On Windows, this function uses the IsDebuggerPresent()
/// function.
/// On Unix, this function returns true if the environment
/// variable POCO_ENABLE_DEBUGGER is set.
static void message(const std::string& msg);
/// Writes a message to the debugger log, if available, otherwise to
/// standard error output.
static void message(const std::string& msg, const char* file, int line);
/// Writes a message to the debugger log, if available, otherwise to
/// standard error output.
static void enter();
/// Breaks into the debugger, if it is available.
/// On Windows, this is done using the DebugBreak() function.
/// On Unix, the SIGINT signal is raised.
static void enter(const std::string& msg);
/// Writes a debug message to the debugger log and breaks into it.
static void enter(const std::string& msg, const char* file, int line);
/// Writes a debug message to the debugger log and breaks into it.
static void enter(const char* file, int line);
/// Writes a debug message to the debugger log and breaks into it.
};
} // namespace Poco
#endif // Foundation_Debugger_INCLUDED

View File

@ -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 <vector>
namespace Poco {
template <class TArgs, class TDelegate>
class DefaultStrategy: public NotificationStrategy<TArgs, TDelegate>
/// 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<TDelegate>;
using Delegates = std::vector<DelegatePtr>;
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<TDelegate*>(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 TDelegate>
class DefaultStrategy<void,TDelegate>: public NotificationStrategy<void, TDelegate>
/// 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<TDelegate>;
using Delegates = std::vector<DelegatePtr>;
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<TDelegate*>(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

View File

@ -0,0 +1,201 @@
//
// DeflatingStream.h
//
// Library: Foundation
// Package: Streams
// Module: ZLibStream
//
// Definition of the DeflatingStream class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DeflatingStream_INCLUDED
#define Foundation_DeflatingStream_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/BufferedStreamBuf.h"
#include <istream>
#include <ostream>
#if defined(POCO_UNBUNDLED)
#include <zlib.h>
#else
#include "Poco/zlib.h"
#endif
namespace Poco {
class Foundation_API DeflatingStreamBuf: public BufferedStreamBuf
/// This is the streambuf class used by DeflatingInputStream and DeflatingOutputStream.
/// The actual work is delegated to zlib (see http://zlib.net).
/// Both zlib (deflate) streams and gzip streams are supported.
/// Output streams should always call close() to ensure
/// proper completion of compression.
/// A compression level (0 to 9) can be specified in the constructor.
{
public:
enum StreamType
{
STREAM_ZLIB, /// Create a zlib header, use Adler-32 checksum.
STREAM_GZIP /// Create a gzip header, use CRC-32 checksum.
};
DeflatingStreamBuf(std::istream& istr, StreamType type, int level);
/// Creates a DeflatingStreamBuf for compressing data read
/// from the given input stream.
DeflatingStreamBuf(std::istream& istr, int windowBits, int level);
/// Creates a DeflatingStreamBuf for compressing data read
/// from the given input stream.
///
/// Please refer to the zlib documentation of deflateInit2() for a description
/// of the windowBits parameter.
DeflatingStreamBuf(std::ostream& ostr, StreamType type, int level);
/// Creates a DeflatingStreamBuf for compressing data passed
/// through and forwarding it to the given output stream.
DeflatingStreamBuf(std::ostream& ostr, int windowBits, int level);
/// Creates a DeflatingStreamBuf for compressing data passed
/// through and forwarding it to the given output stream.
///
/// Please refer to the zlib documentation of deflateInit2() for a description
/// of the windowBits parameter.
~DeflatingStreamBuf();
/// Destroys the DeflatingStreamBuf.
int close();
/// Finishes up the stream.
///
/// Must be called when deflating to an output stream.
protected:
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length);
virtual int sync();
private:
enum
{
STREAM_BUFFER_SIZE = 1024,
DEFLATE_BUFFER_SIZE = 32768
};
std::istream* _pIstr;
std::ostream* _pOstr;
char* _buffer;
z_stream _zstr;
bool _eof;
};
class Foundation_API DeflatingIOS: public virtual std::ios
/// The base class for DeflatingOutputStream and DeflatingInputStream.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
DeflatingIOS(std::ostream& ostr, DeflatingStreamBuf::StreamType type = DeflatingStreamBuf::STREAM_ZLIB, int level = Z_DEFAULT_COMPRESSION);
/// Creates a DeflatingIOS for compressing data passed
/// through and forwarding it to the given output stream.
DeflatingIOS(std::ostream& ostr, int windowBits, int level);
/// Creates a DeflatingIOS for compressing data passed
/// through and forwarding it to the given output stream.
///
/// Please refer to the zlib documentation of deflateInit2() for a description
/// of the windowBits parameter.
DeflatingIOS(std::istream& istr, DeflatingStreamBuf::StreamType type = DeflatingStreamBuf::STREAM_ZLIB, int level = Z_DEFAULT_COMPRESSION);
/// Creates a DeflatingIOS for compressing data read
/// from the given input stream.
DeflatingIOS(std::istream& istr, int windowBits, int level);
/// Creates a DeflatingIOS for compressing data read
/// from the given input stream.
///
/// Please refer to the zlib documentation of deflateInit2() for a description
/// of the windowBits parameter.
~DeflatingIOS();
/// Destroys the DeflatingIOS.
DeflatingStreamBuf* rdbuf();
/// Returns a pointer to the underlying stream buffer.
protected:
DeflatingStreamBuf _buf;
};
class Foundation_API DeflatingOutputStream: public std::ostream, public DeflatingIOS
/// This stream compresses all data passing through it
/// using zlib's deflate algorithm.
/// After all data has been written to the stream, close()
/// must be called to ensure completion of compression.
/// Example:
/// std::ofstream ostr("data.gz", std::ios::binary);
/// DeflatingOutputStream deflater(ostr, DeflatingStreamBuf::STREAM_GZIP);
/// deflater << "Hello, world!" << std::endl;
/// deflater.close();
/// ostr.close();
{
public:
DeflatingOutputStream(std::ostream& ostr, DeflatingStreamBuf::StreamType type = DeflatingStreamBuf::STREAM_ZLIB, int level = Z_DEFAULT_COMPRESSION);
/// Creates a DeflatingOutputStream for compressing data passed
/// through and forwarding it to the given output stream.
DeflatingOutputStream(std::ostream& ostr, int windowBits, int level);
/// Creates a DeflatingOutputStream for compressing data passed
/// through and forwarding it to the given output stream.
///
/// Please refer to the zlib documentation of deflateInit2() for a description
/// of the windowBits parameter.
~DeflatingOutputStream();
/// Destroys the DeflatingOutputStream.
int close();
/// Finishes up the stream.
///
/// Must be called when deflating to an output stream.
protected:
virtual int sync();
};
class Foundation_API DeflatingInputStream: public std::istream, public DeflatingIOS
/// This stream compresses all data passing through it
/// using zlib's deflate algorithm.
{
public:
DeflatingInputStream(std::istream& istr, DeflatingStreamBuf::StreamType type = DeflatingStreamBuf::STREAM_ZLIB, int level = Z_DEFAULT_COMPRESSION);
/// Creates a DeflatingIOS for compressing data read
/// from the given input stream.
DeflatingInputStream(std::istream& istr, int windowBits, int level);
/// Creates a DeflatingIOS for compressing data read
/// from the given input stream.
///
/// Please refer to the zlib documentation of deflateInit2() for a description
/// of the windowBits parameter.
~DeflatingInputStream();
/// Destroys the DeflatingInputStream.
};
} // namespace Poco
#endif // Foundation_DeflatingStream_INCLUDED

View File

@ -0,0 +1,452 @@
//
// Delegate.h
//
// Library: Foundation
// Package: Events
// Module: Delegate
//
// Implementation of the Delegate template.
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Delegate_INCLUDED
#define Foundation_Delegate_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/AbstractDelegate.h"
#include "Poco/FunctionDelegate.h"
#include "Poco/Expire.h"
#include "Poco/Mutex.h"
namespace Poco {
template <class TObj, class TArgs, bool withSender = true>
class Delegate: public AbstractDelegate<TArgs>
{
public:
typedef void (TObj::*NotifyMethod)(const void*, TArgs&);
Delegate(TObj* obj, NotifyMethod method):
_receiverObject(obj),
_receiverMethod(method)
{
}
Delegate(const Delegate& delegate):
AbstractDelegate<TArgs>(delegate),
_receiverObject(delegate._receiverObject),
_receiverMethod(delegate._receiverMethod)
{
}
~Delegate()
{
}
Delegate& operator = (const Delegate& delegate)
{
if (&delegate != this)
{
this->_receiverObject = delegate._receiverObject;
this->_receiverMethod = delegate._receiverMethod;
}
return *this;
}
bool notify(const void* sender, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverObject)
{
(_receiverObject->*_receiverMethod)(sender, arguments);
return true;
}
else return false;
}
bool equals(const AbstractDelegate<TArgs>& other) const
{
const Delegate* pOtherDelegate = dynamic_cast<const Delegate*>(other.unwrap());
return pOtherDelegate && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod;
}
AbstractDelegate<TArgs>* clone() const
{
return new Delegate(*this);
}
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverObject = 0;
}
protected:
TObj* _receiverObject;
NotifyMethod _receiverMethod;
Mutex _mutex;
private:
Delegate();
};
template <class TObj, class TArgs>
class Delegate<TObj, TArgs, false>: public AbstractDelegate<TArgs>
{
public:
typedef void (TObj::*NotifyMethod)(TArgs&);
Delegate(TObj* obj, NotifyMethod method):
_receiverObject(obj),
_receiverMethod(method)
{
}
Delegate(const Delegate& delegate):
AbstractDelegate<TArgs>(delegate),
_receiverObject(delegate._receiverObject),
_receiverMethod(delegate._receiverMethod)
{
}
~Delegate()
{
}
Delegate& operator = (const Delegate& delegate)
{
if (&delegate != this)
{
this->_receiverObject = delegate._receiverObject;
this->_receiverMethod = delegate._receiverMethod;
}
return *this;
}
bool notify(const void*, TArgs& arguments)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverObject)
{
(_receiverObject->*_receiverMethod)(arguments);
return true;
}
else return false;
}
bool equals(const AbstractDelegate<TArgs>& other) const
{
const Delegate* pOtherDelegate = dynamic_cast<const Delegate*>(other.unwrap());
return pOtherDelegate && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod;
}
AbstractDelegate<TArgs>* clone() const
{
return new Delegate(*this);
}
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverObject = 0;
}
protected:
TObj* _receiverObject;
NotifyMethod _receiverMethod;
Mutex _mutex;
private:
Delegate();
};
template <class TObj, class TArgs>
inline Delegate<TObj, TArgs, true> delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&))
{
return Delegate<TObj, TArgs, true>(pObj, NotifyMethod);
}
template <class TObj, class TArgs>
inline Delegate<TObj, TArgs, false> delegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&))
{
return Delegate<TObj, TArgs, false>(pObj, NotifyMethod);
}
template <class TObj, class TArgs>
inline Expire<TArgs> delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), Timestamp::TimeDiff expireMillisecs)
{
return Expire<TArgs>(Delegate<TObj, TArgs, true>(pObj, NotifyMethod), expireMillisecs);
}
template <class TObj, class TArgs>
inline Expire<TArgs> delegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&), Timestamp::TimeDiff expireMillisecs)
{
return Expire<TArgs>(Delegate<TObj, TArgs, false>(pObj, NotifyMethod), expireMillisecs);
}
template <class TArgs>
inline Expire<TArgs> delegate(void (*NotifyMethod)(const void*, TArgs&), Timestamp::TimeDiff expireMillisecs)
{
return Expire<TArgs>(FunctionDelegate<TArgs, true, true>(NotifyMethod), expireMillisecs);
}
template <class TArgs>
inline Expire<TArgs> delegate(void (*NotifyMethod)(void*, TArgs&), Timestamp::TimeDiff expireMillisecs)
{
return Expire<TArgs>(FunctionDelegate<TArgs, true, false>(NotifyMethod), expireMillisecs);
}
template <class TArgs>
inline Expire<TArgs> delegate(void (*NotifyMethod)(TArgs&), Timestamp::TimeDiff expireMillisecs)
{
return Expire<TArgs>(FunctionDelegate<TArgs, false>(NotifyMethod), expireMillisecs);
}
template <class TArgs>
inline FunctionDelegate<TArgs, true, true> delegate(void (*NotifyMethod)(const void*, TArgs&))
{
return FunctionDelegate<TArgs, true, true>(NotifyMethod);
}
template <class TArgs>
inline FunctionDelegate<TArgs, true, false> delegate(void (*NotifyMethod)(void*, TArgs&))
{
return FunctionDelegate<TArgs, true, false>(NotifyMethod);
}
template <class TArgs>
inline FunctionDelegate<TArgs, false> delegate(void (*NotifyMethod)(TArgs&))
{
return FunctionDelegate<TArgs, false>(NotifyMethod);
}
template <class TObj>
class Delegate<TObj,void,true>: public AbstractDelegate<void>
{
public:
typedef void (TObj::*NotifyMethod)(const void*);
Delegate(TObj* obj, NotifyMethod method):
_receiverObject(obj),
_receiverMethod(method)
{
}
Delegate(const Delegate& delegate):
AbstractDelegate<void>(delegate),
_receiverObject(delegate._receiverObject),
_receiverMethod(delegate._receiverMethod)
{
}
~Delegate()
{
}
Delegate& operator = (const Delegate& delegate)
{
if (&delegate != this)
{
this->_receiverObject = delegate._receiverObject;
this->_receiverMethod = delegate._receiverMethod;
}
return *this;
}
bool notify(const void* sender)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverObject)
{
(_receiverObject->*_receiverMethod)(sender);
return true;
}
else return false;
}
bool equals(const AbstractDelegate<void>& other) const
{
const Delegate* pOtherDelegate = dynamic_cast<const Delegate*>(other.unwrap());
return pOtherDelegate && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod;
}
AbstractDelegate<void>* clone() const
{
return new Delegate(*this);
}
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverObject = 0;
}
protected:
TObj* _receiverObject;
NotifyMethod _receiverMethod;
Mutex _mutex;
private:
Delegate();
};
template <class TObj>
class Delegate<TObj, void, false>: public AbstractDelegate<void>
{
public:
typedef void (TObj::*NotifyMethod)();
Delegate(TObj* obj, NotifyMethod method):
_receiverObject(obj),
_receiverMethod(method)
{
}
Delegate(const Delegate& delegate):
AbstractDelegate<void>(delegate),
_receiverObject(delegate._receiverObject),
_receiverMethod(delegate._receiverMethod)
{
}
~Delegate()
{
}
Delegate& operator = (const Delegate& delegate)
{
if (&delegate != this)
{
this->_receiverObject = delegate._receiverObject;
this->_receiverMethod = delegate._receiverMethod;
}
return *this;
}
bool notify(const void*)
{
Mutex::ScopedLock lock(_mutex);
if (_receiverObject)
{
(_receiverObject->*_receiverMethod)();
return true;
}
else return false;
}
bool equals(const AbstractDelegate<void>& other) const
{
const Delegate* pOtherDelegate = dynamic_cast<const Delegate*>(other.unwrap());
return pOtherDelegate && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod;
}
AbstractDelegate<void>* clone() const
{
return new Delegate(*this);
}
void disable()
{
Mutex::ScopedLock lock(_mutex);
_receiverObject = 0;
}
protected:
TObj* _receiverObject;
NotifyMethod _receiverMethod;
Mutex _mutex;
private:
Delegate();
};
template <class TObj>
inline Delegate<TObj, void, true> delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*))
{
return Delegate<TObj, void, true>(pObj, NotifyMethod);
}
template <class TObj>
inline Delegate<TObj, void, false> delegate(TObj* pObj, void (TObj::*NotifyMethod)())
{
return Delegate<TObj, void, false>(pObj, NotifyMethod);
}
template <class TObj>
inline Expire<void> delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*), Timestamp::TimeDiff expireMillisecs)
{
return Expire<void>(Delegate<TObj, void, true>(pObj, NotifyMethod), expireMillisecs);
}
template <class TObj>
inline Expire<void> delegate(TObj* pObj, void (TObj::*NotifyMethod)(), Timestamp::TimeDiff expireMillisecs)
{
return Expire<void>(Delegate<TObj, void, false>(pObj, NotifyMethod), expireMillisecs);
}
inline Expire<void> delegate(void (*NotifyMethod)(const void*), Timestamp::TimeDiff expireMillisecs)
{
return Expire<void>(FunctionDelegate<void, true, true>(NotifyMethod), expireMillisecs);
}
inline Expire<void> delegate(void (*NotifyMethod)(void*), Timestamp::TimeDiff expireMillisecs)
{
return Expire<void>(FunctionDelegate<void, true, false>(NotifyMethod), expireMillisecs);
}
inline Expire<void> delegate(void (*NotifyMethod)(), Timestamp::TimeDiff expireMillisecs)
{
return Expire<void>(FunctionDelegate<void, false>(NotifyMethod), expireMillisecs);
}
inline FunctionDelegate<void, true, true> delegate(void (*NotifyMethod)(const void*))
{
return FunctionDelegate<void, true, true>(NotifyMethod);
}
inline FunctionDelegate<void, true, false> delegate(void (*NotifyMethod)(void*))
{
return FunctionDelegate<void, true, false>(NotifyMethod);
}
inline FunctionDelegate<void, false> delegate(void (*NotifyMethod)())
{
return FunctionDelegate<void, false>(NotifyMethod);
}
} // namespace Poco
#endif // Foundation_Delegate_INCLUDED

View File

@ -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 <vector>
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<unsigned char>;
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 <https://codahale.com/a-lesson-in-timing-attacks/>).
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

View File

@ -0,0 +1,100 @@
//
// DigestStream.h
//
// Library: Foundation
// Package: Crypt
// Module: DigestStream
//
// Definition of classes DigestInputStream and DigestOutputStream.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DigestStream_INCLUDED
#define Foundation_DigestStream_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/BufferedStreamBuf.h"
#include "Poco/DigestEngine.h"
#include <istream>
#include <ostream>
namespace Poco {
class Foundation_API DigestBuf: public BufferedStreamBuf
/// This streambuf computes a digest of all data going
/// through it.
{
public:
DigestBuf(DigestEngine& eng);
DigestBuf(DigestEngine& eng, std::istream& istr);
DigestBuf(DigestEngine& eng, std::ostream& ostr);
~DigestBuf();
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length);
void close();
private:
DigestEngine& _eng;
std::istream* _pIstr;
std::ostream* _pOstr;
static const int BUFFER_SIZE;
};
class Foundation_API DigestIOS: public virtual std::ios
/// The base class for DigestInputStream and DigestOutputStream.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
DigestIOS(DigestEngine& eng);
DigestIOS(DigestEngine& eng, std::istream& istr);
DigestIOS(DigestEngine& eng, std::ostream& ostr);
~DigestIOS();
DigestBuf* rdbuf();
protected:
DigestBuf _buf;
};
class Foundation_API DigestInputStream: public DigestIOS, public std::istream
/// This istream computes a digest of
/// all the data passing through it,
/// using a DigestEngine.
{
public:
DigestInputStream(DigestEngine& eng, std::istream& istr);
~DigestInputStream();
};
class Foundation_API DigestOutputStream: public DigestIOS, public std::ostream
/// This ostream computes a digest of
/// all the data passing through it,
/// using a DigestEngine.
/// To ensure that all data has been incorporated
/// into the digest, call close() or flush() before
/// you obtain the digest from the digest engine.
{
public:
DigestOutputStream(DigestEngine& eng);
DigestOutputStream(DigestEngine& eng, std::ostream& ostr);
~DigestOutputStream();
void close();
};
} // namespace Poco
#endif // Foundation_DigestStream_INCLUDED

View File

@ -0,0 +1,153 @@
//
// DirectoryIterator.h
//
// Library: Foundation
// Package: Filesystem
// Module: DirectoryIterator
//
// Definition of the DirectoryIterator class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DirectoryIterator_INCLUDED
#define Foundation_DirectoryIterator_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/File.h"
#include "Poco/Path.h"
namespace Poco {
class DirectoryIteratorImpl;
class Foundation_API DirectoryIterator
/// The DirectoryIterator class is used to enumerate
/// all files in a directory.
///
/// DirectoryIterator has some limitations:
/// * only forward iteration (++) is supported
/// * an iterator copied from another one will always
/// point to the same file as the original iterator,
/// even is the original iterator has been advanced
/// (all copies of an iterator share their state with
/// the original iterator)
/// * because of this you should only use the prefix
/// increment operator
{
public:
DirectoryIterator();
/// Creates the end iterator.
DirectoryIterator(const std::string& path);
/// Creates a directory iterator for the given path.
DirectoryIterator(const DirectoryIterator& iterator);
/// Creates a directory iterator for the given path.
DirectoryIterator(const File& file);
/// Creates a directory iterator for the given file.
DirectoryIterator(const Path& path);
/// Creates a directory iterator for the given path.
virtual ~DirectoryIterator();
/// Destroys the DirectoryIterator.
const std::string& name() const;
/// Returns the current filename.
const Path& path() const;
/// Returns the current path.
DirectoryIterator& operator = (const DirectoryIterator& it);
DirectoryIterator& operator = (const File& file);
DirectoryIterator& operator = (const Path& path);
DirectoryIterator& operator = (const std::string& path);
virtual DirectoryIterator& operator ++ (); // prefix
//@ deprecated
DirectoryIterator operator ++ (int); // postfix
/// Please use the prefix increment operator instead.
const File& operator * () const;
File& operator * ();
const File* operator -> () const;
File* operator -> ();
bool operator == (const DirectoryIterator& iterator) const;
bool operator != (const DirectoryIterator& iterator) const;
protected:
Path _path;
File _file;
private:
DirectoryIteratorImpl* _pImpl;
};
//
// inlines
//
inline const std::string& DirectoryIterator::name() const
{
return _path.getFileName();
}
inline const Path& DirectoryIterator::path() const
{
return _path;
}
inline const File& DirectoryIterator::operator * () const
{
return _file;
}
inline File& DirectoryIterator::operator * ()
{
return _file;
}
inline const File* DirectoryIterator::operator -> () const
{
return &_file;
}
inline File* DirectoryIterator::operator -> ()
{
return &_file;
}
inline bool DirectoryIterator::operator == (const DirectoryIterator& iterator) const
{
return name() == iterator.name();
}
inline bool DirectoryIterator::operator != (const DirectoryIterator& iterator) const
{
return name() != iterator.name();
}
} // namespace Poco
#endif // Foundation_DirectoryIterator_INCLUDED

View File

@ -0,0 +1,92 @@
//
// RecursiveDirectoryIteratorStategies.h
//
// Library: Foundation
// Package: Filesystem
// Module: RecursiveDirectoryIterator
//
// Definitions of the RecursiveDirectoryIterator stategy classes.
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_RecursiveDirectoryIteratorStrategy_INCLUDED
#define Foundation_RecursiveDirectoryIteratorStrategy_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/DirectoryIterator.h"
#include <stack>
#include <queue>
#include <functional>
namespace Poco {
class Foundation_API TraverseBase
{
public:
using Stack = std::stack<DirectoryIterator>;
using DepthFun = std::function<UInt16(const Stack&)>;
enum
{
D_INFINITE = 0 /// Special value for infinite traverse depth.
};
TraverseBase(DepthFun depthDeterminer, UInt16 maxDepth = D_INFINITE);
protected:
bool isFiniteDepth();
bool isDirectory(Poco::File& file);
DepthFun _depthDeterminer;
UInt16 _maxDepth;
DirectoryIterator _itEnd;
private:
TraverseBase();
TraverseBase(const TraverseBase&);
TraverseBase& operator=(const TraverseBase&);
};
class Foundation_API ChildrenFirstTraverse: public TraverseBase
{
public:
ChildrenFirstTraverse(DepthFun depthDeterminer, UInt16 maxDepth = D_INFINITE);
const std::string next(Stack* itStack, bool* isFinished);
private:
ChildrenFirstTraverse();
ChildrenFirstTraverse(const ChildrenFirstTraverse&);
ChildrenFirstTraverse& operator=(const ChildrenFirstTraverse&);
};
class Foundation_API SiblingsFirstTraverse: public TraverseBase
{
public:
SiblingsFirstTraverse(DepthFun depthDeterminer, UInt16 maxDepth = D_INFINITE);
const std::string next(Stack* itStack, bool* isFinished);
private:
SiblingsFirstTraverse();
SiblingsFirstTraverse(const SiblingsFirstTraverse&);
SiblingsFirstTraverse& operator=(const SiblingsFirstTraverse&);
std::stack<std::queue<std::string>> _dirsStack;
};
} // namespace Poco
#endif // Foundation_RecursiveDirectoryIteratorStrategy_INCLUDED

View File

@ -0,0 +1,72 @@
//
// DirectoryIterator_UNIX.h
//
// Library: Foundation
// Package: Filesystem
// Module: DirectoryIterator
//
// Definition of the DirectoryIteratorImpl class for UNIX.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DirectoryIterator_UNIX_INCLUDED
#define Foundation_DirectoryIterator_UNIX_INCLUDED
#include "Poco/Foundation.h"
#include <dirent.h>
namespace Poco {
class Foundation_API DirectoryIteratorImpl
{
public:
DirectoryIteratorImpl(const std::string& path);
~DirectoryIteratorImpl();
void duplicate();
void release();
const std::string& get() const;
const std::string& next();
private:
DIR* _pDir;
std::string _current;
int _rc;
};
//
// inlines
//
const std::string& DirectoryIteratorImpl::get() const
{
return _current;
}
inline void DirectoryIteratorImpl::duplicate()
{
++_rc;
}
inline void DirectoryIteratorImpl::release()
{
if (--_rc == 0)
delete this;
}
} // namespace Poco
#endif // Foundation_DirectoryIterator_UNIX_INCLUDED

View File

@ -0,0 +1,73 @@
//
// DirectoryIterator_WIN32U.h
//
// Library: Foundation
// Package: Filesystem
// Module: DirectoryIterator
//
// Definition of the DirectoryIteratorImpl class for WIN32.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DirectoryIterator_WIN32U_INCLUDED
#define Foundation_DirectoryIterator_WIN32U_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/UnWindows.h"
namespace Poco {
class Foundation_API DirectoryIteratorImpl
{
public:
DirectoryIteratorImpl(const std::string& path);
~DirectoryIteratorImpl();
void duplicate();
void release();
const std::string& get() const;
const std::string& next();
private:
HANDLE _fh;
WIN32_FIND_DATAW _fd;
std::string _current;
int _rc;
};
//
// inlines
//
const std::string& DirectoryIteratorImpl::get() const
{
return _current;
}
inline void DirectoryIteratorImpl::duplicate()
{
++_rc;
}
inline void DirectoryIteratorImpl::release()
{
if (--_rc == 0)
delete this;
}
} // namespace Poco
#endif // Foundation_DirectoryIterator_WIN32U_INCLUDED

View File

@ -0,0 +1,232 @@
//
// DirectoryWatcher.h
//
// Library: Foundation
// Package: Filesystem
// Module: DirectoryWatcher
//
// Definition of the DirectoryWatcher class.
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DirectoryWatcher_INCLUDED
#define Foundation_DirectoryWatcher_INCLUDED
#include "Poco/Foundation.h"
#ifndef POCO_NO_INOTIFY
#include "Poco/File.h"
#include "Poco/BasicEvent.h"
#include "Poco/Runnable.h"
#include "Poco/Thread.h"
#include "Poco/AtomicCounter.h"
namespace Poco {
class DirectoryWatcherStrategy;
class Foundation_API DirectoryWatcher: protected Runnable
/// This class is used to get notifications about changes
/// to the filesystem, more specifically, to a specific
/// directory. Changes to a directory are reported via
/// events.
///
/// A thread will be created that watches the specified
/// directory for changes. Events are reported in the context
/// of this thread.
///
/// Note that changes to files in subdirectories of the watched
/// directory are not reported. Separate DirectoryWatcher objects
/// must be created for these directories if they should be watched.
///
/// Changes to file attributes are not reported.
///
/// On Windows, this class is implemented using FindFirstChangeNotification()/FindNextChangeNotification().
/// On Linux, this class is implemented using inotify.
/// On FreeBSD and Darwin (Mac OS X, iOS), this class uses kevent/kqueue.
/// On all other platforms, the watched directory is periodically scanned
/// for changes. This can negatively affect performance if done too often.
/// Therefore, the interval in which scans are done can be specified in
/// the constructor. Note that periodic scanning will also be done on FreeBSD
/// and Darwin if events for changes to files (DW_ITEM_MODIFIED) are enabled.
///
/// DW_ITEM_MOVED_FROM and DW_ITEM_MOVED_TO events will only be reported
/// on Linux. On other platforms, a file rename or move operation
/// will be reported via a DW_ITEM_REMOVED and a DW_ITEM_ADDED event.
/// The order of these two events is not defined.
///
/// An event mask can be specified to enable only certain events.
{
public:
enum DirectoryEventType
{
DW_ITEM_ADDED = 1,
/// A new item has been created and added to the directory.
DW_ITEM_REMOVED = 2,
/// An item has been removed from the directory.
DW_ITEM_MODIFIED = 4,
/// An item has been modified.
DW_ITEM_MOVED_FROM = 8,
/// An item has been renamed or moved. This event delivers the old name.
DW_ITEM_MOVED_TO = 16
/// An item has been renamed or moved. This event delivers the new name.
};
enum DirectoryEventMask
{
DW_FILTER_ENABLE_ALL = 31,
/// Enables all event types.
DW_FILTER_DISABLE_ALL = 0
/// Disables all event types.
};
enum
{
DW_DEFAULT_SCAN_INTERVAL = 5 /// Default scan interval for platforms that don't provide a native notification mechanism.
};
struct DirectoryEvent
{
DirectoryEvent(const File& f, DirectoryEventType ev):
item(f),
event(ev)
{
}
const File& item; /// The directory or file that has been changed.
DirectoryEventType event; /// The kind of event.
};
BasicEvent<const DirectoryEvent> itemAdded;
/// Fired when a file or directory has been created or added to the directory.
BasicEvent<const DirectoryEvent> itemRemoved;
/// Fired when a file or directory has been removed from the directory.
BasicEvent<const DirectoryEvent> itemModified;
/// Fired when a file or directory has been modified.
BasicEvent<const DirectoryEvent> itemMovedFrom;
/// Fired when a file or directory has been renamed. This event delivers the old name.
BasicEvent<const DirectoryEvent> itemMovedTo;
/// Fired when a file or directory has been moved. This event delivers the new name.
BasicEvent<const Exception> scanError;
/// Fired when an error occurs while scanning for changes.
DirectoryWatcher(const std::string& path, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL);
/// Creates a DirectoryWatcher for the directory given in path.
/// To enable only specific events, an eventMask can be specified by
/// OR-ing the desired event IDs (e.g., DW_ITEM_ADDED | DW_ITEM_MODIFIED).
/// On platforms where no native filesystem notifications are available,
/// scanInterval specifies the interval in seconds between scans
/// of the directory.
DirectoryWatcher(const File& directory, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL);
/// Creates a DirectoryWatcher for the specified directory
/// To enable only specific events, an eventMask can be specified by
/// OR-ing the desired event IDs (e.g., DW_ITEM_ADDED | DW_ITEM_MODIFIED).
/// On platforms where no native filesystem notifications are available,
/// scanInterval specifies the interval in seconds between scans
/// of the directory.
~DirectoryWatcher();
/// Destroys the DirectoryWatcher.
void suspendEvents();
/// Suspends sending of events. Can be called multiple times, but every
/// call to suspendEvent() must be matched by a call to resumeEvents().
void resumeEvents();
/// Resumes events, after they have been suspended with a call to suspendEvents().
bool eventsSuspended() const;
/// Returns true iff events are suspended.
int eventMask() const;
/// Returns the value of the eventMask passed to the constructor.
int scanInterval() const;
/// Returns the scan interval in seconds.
const File& directory() const;
/// Returns the directory being watched.
bool supportsMoveEvents() const;
/// Returns true iff the platform supports DW_ITEM_MOVED_FROM/itemMovedFrom and
/// DW_ITEM_MOVED_TO/itemMovedTo events.
protected:
void init();
void stop();
void run();
private:
DirectoryWatcher();
DirectoryWatcher(const DirectoryWatcher&);
DirectoryWatcher& operator = (const DirectoryWatcher&);
Thread _thread;
File _directory;
int _eventMask;
AtomicCounter _eventsSuspended;
int _scanInterval;
DirectoryWatcherStrategy* _pStrategy;
};
//
// inlines
//
inline bool DirectoryWatcher::eventsSuspended() const
{
return _eventsSuspended.value() > 0;
}
inline int DirectoryWatcher::eventMask() const
{
return _eventMask;
}
inline int DirectoryWatcher::scanInterval() const
{
return _scanInterval;
}
inline const File& DirectoryWatcher::directory() const
{
return _directory;
}
} // namespace Poco
#endif // POCO_NO_INOTIFY
#endif // Foundation_DirectoryWatcher_INCLUDED

View File

@ -0,0 +1,412 @@
//
// Pair.h
//
// Library: Foundation
// Package: Dynamic
// Module: Pair
//
// Definition of the Pair class.
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Pair_INCLUDED
#define Foundation_Pair_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Dynamic/Var.h"
#include "Poco/Dynamic/VarHolder.h"
#include <utility>
namespace Poco {
namespace Dynamic {
template <typename K>
class Pair
/// Pair allows to define a pair of values.
{
public:
using Data = typename std::pair<K, Var>;
Pair(): _data()
/// Creates an empty Pair
{
}
Pair(const Pair& other): _data(other._data)
/// Creates the Pair from another pair.
{
}
Pair(const Data& val): _data(val)
/// Creates the Pair from the given value.
{
}
template <typename T>
Pair(const std::pair<K, T>& val): _data(std::make_pair(val.first, val.second))
/// Creates Pair form standard pair.
{
}
template <typename T>
Pair(const K& first, const T& second): _data(std::make_pair(first, second))
/// Creates pair from two values.
{
}
virtual ~Pair()
/// Destroys the Pair.
{
}
Pair& swap(Pair& other)
/// Swaps the content of the two Pairs.
{
std::swap(_data, other._data);
return *this;
}
Pair& operator = (const Pair& other)
/// Copy constructs Pair from another pair.
{
Pair(other).swap(*this);
return *this;
}
inline const K& first() const
/// Returns the first member of the pair.
{
return _data.first;
}
inline const Var& second() const
/// Returns the second member of the pair.
{
return _data.second;
}
std::string toString()
{
std::string str;
Var(*this).template convert<std::string>(str);
return str;
}
private:
Data _data;
};
template <>
class VarHolderImpl<Pair<std::string>>: public VarHolder
{
public:
VarHolderImpl(const Pair<std::string>& val): _val(val)
{
}
~VarHolderImpl()
{
}
const std::type_info& type() const
{
return typeid(Pair<std::string>);
}
void convert(Int8& val) const
{
throw BadCastException("Cannot cast Pair type to Int8");
}
void convert(Int16& val) const
{
throw BadCastException("Cannot cast Pair type to Int16");
}
void convert(Int32& val) const
{
throw BadCastException("Cannot cast Pair type to Int32");
}
void convert(Int64& val) const
{
throw BadCastException("Cannot cast Pair type to Int64");
}
void convert(UInt8& val) const
{
throw BadCastException("Cannot cast Pair type to UInt8");
}
void convert(UInt16& val) const
{
throw BadCastException("Cannot cast Pair type to UInt16");
}
void convert(UInt32& val) const
{
throw BadCastException("Cannot cast Pair type to UInt32");
}
void convert(UInt64& val) const
{
throw BadCastException("Cannot cast Pair type to UInt64");
}
void convert(bool& val) const
{
throw BadCastException("Cannot cast Pair type to bool");
}
void convert(float& val) const
{
throw BadCastException("Cannot cast Pair type to float");
}
void convert(double& val) const
{
throw BadCastException("Cannot cast Pair type to double");
}
void convert(char& val) const
{
throw BadCastException("Cannot cast Pair type to char");
}
void convert(std::string& val) const
{
// Serialize in JSON format: equals an object
// JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
val.append("{ ");
Var key(_val.first());
Impl::appendJSONKey(val, key);
val.append(" : ");
Impl::appendJSONValue(val, _val.second());
val.append(" }");
}
void convert(Poco::DateTime&) const
{
throw BadCastException("Pair -> Poco::DateTime");
}
void convert(Poco::LocalDateTime&) const
{
throw BadCastException("Pair -> Poco::LocalDateTime");
}
void convert(Poco::Timestamp&) const
{
throw BadCastException("Pair -> Poco::Timestamp");
}
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
{
return cloneHolder(pVarHolder, _val);
}
const Pair<std::string>& value() const
{
return _val;
}
bool isArray() const
{
return false;
}
bool isStruct() const
{
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private:
Pair<std::string> _val;
};
template <>
class VarHolderImpl<Pair<int>>: public VarHolder
{
public:
VarHolderImpl(const Pair<int>& val): _val(val)
{
}
~VarHolderImpl()
{
}
const std::type_info& type() const
{
return typeid(Pair<int>);
}
void convert(Int8& val) const
{
throw BadCastException("Cannot cast Pair type to Int8");
}
void convert(Int16& val) const
{
throw BadCastException("Cannot cast Pair type to Int16");
}
void convert(Int32& val) const
{
throw BadCastException("Cannot cast Pair type to Int32");
}
void convert(Int64& val) const
{
throw BadCastException("Cannot cast Pair type to Int64");
}
void convert(UInt8& val) const
{
throw BadCastException("Cannot cast Pair type to UInt8");
}
void convert(UInt16& val) const
{
throw BadCastException("Cannot cast Pair type to UInt16");
}
void convert(UInt32& val) const
{
throw BadCastException("Cannot cast Pair type to UInt32");
}
void convert(UInt64& val) const
{
throw BadCastException("Cannot cast Pair type to UInt64");
}
void convert(bool& val) const
{
throw BadCastException("Cannot cast Pair type to bool");
}
void convert(float& val) const
{
throw BadCastException("Cannot cast Pair type to float");
}
void convert(double& val) const
{
throw BadCastException("Cannot cast Pair type to double");
}
void convert(char& val) const
{
throw BadCastException("Cannot cast Pair type to char");
}
void convert(std::string& val) const
{
// Serialize in JSON format: equals an object
// JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
val.append("{ ");
Var key(_val.first());
Impl::appendJSONKey(val, key);
val.append(" : ");
Impl::appendJSONValue(val, _val.second());
val.append(" }");
}
void convert(Poco::DateTime&) const
{
throw BadCastException("Pair -> Poco::DateTime");
}
void convert(Poco::LocalDateTime&) const
{
throw BadCastException("Pair -> Poco::LocalDateTime");
}
void convert(Poco::Timestamp&) const
{
throw BadCastException("Pair -> Poco::Timestamp");
}
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
{
return cloneHolder(pVarHolder, _val);
}
const Pair<int>& value() const
{
return _val;
}
bool isArray() const
{
return false;
}
bool isStruct() const
{
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private:
Pair<int> _val;
};
} // namespace Dynamic
} // namespace Poco
#endif // Foundation_Pair_INCLUDED

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,155 @@
//
// VarIterator.h
//
// Library: Foundation
// Package: Dynamic
// Module: VarIterator
//
// Definition of the VarIterator class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_VarIterator_INCLUDED
#define Foundation_VarIterator_INCLUDED
#include "Poco/Exception.h"
#include <iterator>
#include <algorithm>
namespace Poco {
namespace Dynamic {
class Var;
class Foundation_API VarIterator
/// VarIterator class.
{
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef Var value_type;
typedef std::ptrdiff_t difference_type;
typedef Var* pointer;
typedef Var& reference;
static const std::size_t POSITION_END;
/// End position indicator.
VarIterator(Var* pVar, bool positionEnd);
/// Creates the VarIterator and positions it at the end of
/// the recordset if positionEnd is true. Otherwise, it is
/// positioned at the beginning.
VarIterator(const VarIterator& other);
/// Creates a copy of other VarIterator.
VarIterator(VarIterator&& other) noexcept;
/// Moves another VarIterator.
~VarIterator();
/// Destroys the VarIterator.
VarIterator& operator = (const VarIterator& other);
/// Assigns the other VarIterator.
VarIterator& operator = (VarIterator&& other) noexcept;
/// Assigns the other VarIterator.
bool operator == (const VarIterator& other) const;
/// Equality operator.
bool operator != (const VarIterator& other) const;
/// Inequality operator.
Var& operator * () const;
/// Returns value at the current position.
Var* operator -> () const;
/// Returns pointer to the value at current position.
const VarIterator& operator ++ () const;
/// Advances by one position and returns current position.
VarIterator operator ++ (int) const;
/// Advances by one position and returns copy of the iterator with
/// previous current position.
const VarIterator& operator -- () const;
/// Goes back by one position and returns copy of the iterator with
/// previous current position.
VarIterator operator -- (int) const;
/// Goes back by one position and returns previous current position.
VarIterator operator + (std::size_t diff) const;
/// Returns a copy the VarIterator advanced by diff positions.
VarIterator operator - (std::size_t diff) const;
/// Returns a copy the VarIterator backed by diff positions.
/// Throws RangeException if diff is larger than current position.
void swap(VarIterator& other);
/// Swaps the VarIterator with another one.
private:
VarIterator();
void increment() const;
/// Increments the iterator position by one.
/// Throws RangeException if position is out of range.
void decrement() const;
/// Decrements the iterator position by one.
/// Throws RangeException if position is out of range.
void setPosition(std::size_t pos) const;
/// Sets the iterator position.
/// Throws RangeException if position is out of range.
Var* _pVar;
mutable std::size_t _position;
friend class Var;
};
///
/// inlines
///
inline bool VarIterator::operator == (const VarIterator& other) const
{
return _pVar == other._pVar && _position == other._position;
}
inline bool VarIterator::operator != (const VarIterator& other) const
{
return _pVar != other._pVar || _position != other._position;
}
} } // namespace Poco::Dynamic
namespace std
{
template<>
inline void swap<Poco::Dynamic::VarIterator>(Poco::Dynamic::VarIterator& s1, Poco::Dynamic::VarIterator& s2) noexcept
/// Full template specialization of std:::swap for VarIterator
{
s1.swap(s2);
}
}
#endif // Foundation_VarIterator_INCLUDED

View File

@ -0,0 +1,24 @@
//
// DynamicAny.h
//
// Library: Foundation
// Package: Dynamic
// Module: Var
//
// Forward header for Var class to maintain backward compatibility.
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DynamicAny_INCLUDED
#define Foundation_DynamicAny_INCLUDED
//@ deprecated
#include "Poco/Dynamic/Var.h"
#endif // Foundation_DynamicAny_INCLUDED

View File

@ -0,0 +1,24 @@
//
// DynamicAnyHolder.h
//
// Library: Foundation
// Package: Dynamic
// Module: VarHolder
//
// Forward header for VarHolder class to maintain backward compatibility
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DynamicAnyHolder_INCLUDED
#define Foundation_DynamicAnyHolder_INCLUDED
//@ deprecated
#include "Poco/Dynamic/VarHolder.h"
#endif // Foundation_DynamicAnyHolder_INCLUDED

View File

@ -0,0 +1,137 @@
//
// DynamicFactory.h
//
// Library: Foundation
// Package: Core
// Module: DynamicFactory
//
// Definition of the DynamicFactory class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DynamicFactory_INCLUDED
#define Foundation_DynamicFactory_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Instantiator.h"
#include "Poco/Exception.h"
#include "Poco/Mutex.h"
#include <map>
#include <memory>
namespace Poco {
template <class Base>
class DynamicFactory
/// A factory that creates objects by class name.
{
public:
typedef AbstractInstantiator<Base> AbstractFactory;
DynamicFactory()
/// Creates the DynamicFactory.
{
}
~DynamicFactory()
/// Destroys the DynamicFactory and deletes the instantiators for
/// all registered classes.
{
for (auto& p: _map)
{
delete p.second;
}
}
Base* createInstance(const std::string& className) const
/// Creates a new instance of the class with the given name.
/// The class must have been registered with registerClass.
/// If the class name is unknown, a NotFoundException is thrown.
{
FastMutex::ScopedLock lock(_mutex);
typename FactoryMap::const_iterator it = _map.find(className);
if (it != _map.end())
return it->second->createInstance();
else
throw NotFoundException(className);
}
template <class C>
void registerClass(const std::string& className)
/// Registers the instantiator for the given class with the DynamicFactory.
/// The DynamicFactory takes ownership of the instantiator and deletes
/// it when it's no longer used.
/// If the class has already been registered, an ExistsException is thrown
/// and the instantiator is deleted.
{
registerClass(className, new Instantiator<C, Base>);
}
void registerClass(const std::string& className, AbstractFactory* pAbstractFactory)
/// Registers the instantiator for the given class with the DynamicFactory.
/// The DynamicFactory takes ownership of the instantiator and deletes
/// it when it's no longer used.
/// If the class has already been registered, an ExistsException is thrown
/// and the instantiator is deleted.
{
poco_check_ptr (pAbstractFactory);
FastMutex::ScopedLock lock(_mutex);
std::unique_ptr<AbstractFactory> ptr(pAbstractFactory);
typename FactoryMap::iterator it = _map.find(className);
if (it == _map.end())
_map[className] = ptr.release();
else
throw ExistsException(className);
}
void unregisterClass(const std::string& className)
/// Unregisters the given class and deletes the instantiator
/// for the class.
/// Throws a NotFoundException if the class has not been registered.
{
FastMutex::ScopedLock lock(_mutex);
typename FactoryMap::iterator it = _map.find(className);
if (it != _map.end())
{
delete it->second;
_map.erase(it);
}
else throw NotFoundException(className);
}
bool isClass(const std::string& className) const
/// Returns true iff the given class has been registered.
{
FastMutex::ScopedLock lock(_mutex);
return _map.find(className) != _map.end();
}
private:
DynamicFactory(const DynamicFactory&);
DynamicFactory& operator = (const DynamicFactory&);
typedef std::map<std::string, AbstractFactory*> FactoryMap;
FactoryMap _map;
mutable FastMutex _mutex;
};
} // namespace Poco
#endif // Foundation_DynamicFactory_INCLUDED

View File

@ -0,0 +1,24 @@
//
// DynamicStruct.h
//
// Library: Foundation
// Package: Dynamic
// Module: Struct
//
// Forward header for Struct class to maintain backward compatibility.
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_DynamicStruct_INCLUDED
#define Foundation_DynamicStruct_INCLUDED
//@ deprecated
#include "Poco/Dynamic/Struct.h"
#endif // Foundation_DynamicStruct_INCLUDED

View File

@ -0,0 +1,123 @@
//
// Environment.h
//
// Library: Foundation
// Package: Core
// Module: Environment
//
// Definition of the Environment class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Environment_INCLUDED
#define Foundation_Environment_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API Environment
/// This class provides access to environment variables
/// and some general system information.
{
public:
typedef UInt8 NodeId[6]; /// Ethernet address.
static std::string get(const std::string& name);
/// Returns the value of the environment variable
/// with the given name. Throws a NotFoundException
/// if the variable does not exist.
static std::string get(const std::string& name, const std::string& defaultValue);
/// Returns the value of the environment variable
/// with the given name. If the environment variable
/// is undefined, returns defaultValue instead.
static bool has(const std::string& name);
/// Returns true iff an environment variable
/// with the given name is defined.
static void set(const std::string& name, const std::string& value);
/// Sets the environment variable with the given name
/// to the given value.
static std::string osName();
/// Returns the operating system name.
static std::string osDisplayName();
/// Returns the operating system name in a
/// "user-friendly" way.
///
/// Currently this is only implemented for
/// Windows. There it will return names like
/// "Windows XP" or "Windows 7/Server 2008 SP2".
/// On other platforms, returns the same as
/// osName().
static std::string osVersion();
/// Returns the operating system version.
static std::string osArchitecture();
/// Returns the operating system architecture.
static std::string nodeName();
/// Returns the node (or host) name.
static void nodeId(NodeId& id);
/// Returns the Ethernet address of the first Ethernet
/// adapter found on the system.
///
/// Throws a SystemException if no Ethernet adapter is available.
static std::string nodeId();
/// Returns the Ethernet address (format "xx:xx:xx:xx:xx:xx")
/// of the first Ethernet adapter found on the system.
///
/// Throws a SystemException if no Ethernet adapter is available.
static unsigned processorCount();
/// Returns the number of processors installed in the system.
///
/// If the number of processors cannot be determined, returns 1.
static Poco::UInt32 libraryVersion();
/// Returns the POCO C++ Libraries version as a hexadecimal
/// number in format 0xAABBCCDD, where
/// - AA is the major version number,
/// - BB is the minor version number,
/// - CC is the revision number, and
/// - DD is the patch level number.
///
/// Some patch level ranges have special meanings:
/// - Dx mark development releases,
/// - Ax mark alpha releases, and
/// - Bx mark beta releases.
static Poco::Int32 os();
/// Return the operating system as defined
/// in the include Foundation/Platform.h (POCO_OS)
static Poco::Int32 arch();
/// Return the underlying cpu architecture that runs this operating system
/// as defined in Foundation/Platform (POCO_ARCH)
static bool isUnix();
/// Return true if the operating system belongs to the Linux family
static bool isWindows();
/// Return true if the operating system belongs to the Windows family
};
} // namespace Poco
#endif // Foundation_Environment_INCLUDED

View File

@ -0,0 +1,56 @@
//
// Environment_UNIX.h
//
// Library: Foundation
// Package: Core
// Module: Environment
//
// Definition of the EnvironmentImpl class for Unix.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Environment_UNIX_INCLUDED
#define Foundation_Environment_UNIX_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Mutex.h"
#include <map>
namespace Poco {
class Foundation_API EnvironmentImpl
{
public:
typedef UInt8 NodeId[6]; /// Ethernet address.
static std::string getImpl(const std::string& name);
static bool hasImpl(const std::string& name);
static void setImpl(const std::string& name, const std::string& value);
static std::string osNameImpl();
static std::string osDisplayNameImpl();
static std::string osVersionImpl();
static std::string osArchitectureImpl();
static std::string nodeNameImpl();
static void nodeIdImpl(NodeId& id);
static unsigned processorCountImpl();
private:
typedef std::map<std::string, std::string> StringMap;
static StringMap _map;
static FastMutex _mutex;
};
} // namespace Poco
#endif // Foundation_Environment_UNIX_INCLUDED

View File

@ -0,0 +1,56 @@
//
// Environment_VX.h
//
// Library: Foundation
// Package: Core
// Module: Environment
//
// Definition of the EnvironmentImpl class for VxWorks.
//
// Copyright (c) 2004-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Environment_VX_INCLUDED
#define Foundation_Environment_VX_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Mutex.h"
#include <map>
namespace Poco {
class Foundation_API EnvironmentImpl
{
public:
typedef UInt8 NodeId[6]; /// Ethernet address.
static std::string getImpl(const std::string& name);
static bool hasImpl(const std::string& name);
static void setImpl(const std::string& name, const std::string& value);
static std::string osNameImpl();
static std::string osDisplayNameImpl();
static std::string osVersionImpl();
static std::string osArchitectureImpl();
static std::string nodeNameImpl();
static void nodeIdImpl(NodeId& id);
static unsigned processorCountImpl();
private:
typedef std::map<std::string, std::string> StringMap;
static StringMap _map;
static FastMutex _mutex;
};
} // namespace Poco
#endif // Foundation_Environment_VX_INCLUDED

View File

@ -0,0 +1,48 @@
//
// Environment_WIN32U.h
//
// Library: Foundation
// Package: Core
// Module: Environment
//
// Definition of the EnvironmentImpl class for WIN32.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Environment_WIN32U_INCLUDED
#define Foundation_Environment_WIN32U_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API EnvironmentImpl
{
public:
typedef UInt8 NodeId[6]; /// Ethernet address.
static std::string getImpl(const std::string& name);
static bool hasImpl(const std::string& name);
static void setImpl(const std::string& name, const std::string& value);
static std::string osNameImpl();
static std::string osDisplayNameImpl();
static std::string osVersionImpl();
static std::string osArchitectureImpl();
static std::string nodeNameImpl();
static void nodeIdImpl(NodeId& id);
static unsigned processorCountImpl();
};
} // namespace Poco
#endif // Foundation_Environment_WIN32U_INCLUDED

View File

@ -0,0 +1,59 @@
//
// Environment_WINCE.h
//
// Library: Foundation
// Package: Core
// Module: Environment
//
// Definition of the EnvironmentImpl class for WINCE.
//
// Copyright (c) 2009-2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Environment_WINCE_INCLUDED
#define Foundation_Environment_WINCE_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API EnvironmentImpl
{
public:
typedef UInt8 NodeId[6]; /// Ethernet address.
static std::string getImpl(const std::string& name);
static bool hasImpl(const std::string& name);
static void setImpl(const std::string& name, const std::string& value);
static std::string osNameImpl();
static std::string osDisplayNameImpl();
static std::string osVersionImpl();
static std::string osArchitectureImpl();
static std::string nodeNameImpl();
static void nodeIdImpl(NodeId& id);
static unsigned processorCountImpl();
private:
static bool envVar(const std::string& name, std::string* value);
static const std::string TEMP;
static const std::string TMP;
static const std::string HOMEPATH;
static const std::string COMPUTERNAME;
static const std::string OS;
static const std::string NUMBER_OF_PROCESSORS;
static const std::string PROCESSOR_ARCHITECTURE;
};
} // namespace Poco
#endif // Foundation_Environment_WINCE_INCLUDED

View File

@ -0,0 +1,52 @@
//
// Error.h
//
// Library: Foundation
// Package: Core
// Module: Error
//
// Definition of the Error class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Error_INCLUDED
#define Foundation_Error_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API Error
/// The Error class provides utility functions
/// for error reporting.
{
public:
#ifdef POCO_OS_FAMILY_WINDOWS
static DWORD last();
/// Utility function returning the last error.
static std::string getMessage(DWORD errorCode);
/// Utility function translating numeric error code to string.
#else
static int last();
/// Utility function returning the last error.
static std::string getMessage(int errorCode);
/// Utility function translating numeric error code to string.
#endif
};
} // namespace Poco
#endif // Foundation_Error_INCLUDED

View File

@ -0,0 +1,120 @@
//
// ErrorHandler.h
//
// Library: Foundation
// Package: Threading
// Module: ErrorHandler
//
// Definition of the ErrorHandler class.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ErrorHandler_INCLUDED
#define Foundation_ErrorHandler_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Exception.h"
#include "Poco/Mutex.h"
namespace Poco {
class Foundation_API ErrorHandler
/// This is the base class for thread error handlers.
///
/// An unhandled exception that causes a thread to terminate is usually
/// silently ignored, since the class library cannot do anything meaningful
/// about it.
///
/// The Thread class provides the possibility to register a
/// global ErrorHandler that is invoked whenever a thread has
/// been terminated by an unhandled exception.
/// The ErrorHandler must be derived from this class and can
/// provide implementations of all three exception() overloads.
///
/// The ErrorHandler is always invoked within the context of
/// the offending thread.
{
public:
ErrorHandler();
/// Creates the ErrorHandler.
virtual ~ErrorHandler();
/// Destroys the ErrorHandler.
virtual void exception(const Exception& exc);
/// Called when a Poco::Exception (or a subclass)
/// caused the thread to terminate.
///
/// This method should not throw any exception - it would
/// be silently ignored.
///
/// The default implementation just breaks into the debugger.
virtual void exception(const std::exception& exc);
/// Called when a std::exception (or a subclass)
/// caused the thread to terminate.
///
/// This method should not throw any exception - it would
/// be silently ignored.
///
/// The default implementation just breaks into the debugger.
virtual void exception();
/// Called when an exception that is neither a
/// Poco::Exception nor a std::exception caused
/// the thread to terminate.
///
/// This method should not throw any exception - it would
/// be silently ignored.
///
/// The default implementation just breaks into the debugger.
static void handle(const Exception& exc);
/// Invokes the currently registered ErrorHandler.
static void handle(const std::exception& exc);
/// Invokes the currently registered ErrorHandler.
static void handle();
/// Invokes the currently registered ErrorHandler.
static ErrorHandler* set(ErrorHandler* pHandler);
/// Registers the given handler as the current error handler.
///
/// Returns the previously registered handler.
static ErrorHandler* get();
/// Returns a pointer to the currently registered
/// ErrorHandler.
protected:
static ErrorHandler* defaultHandler();
/// Returns the default ErrorHandler.
private:
static ErrorHandler* _pHandler;
static FastMutex _mutex;
};
//
// inlines
//
inline ErrorHandler* ErrorHandler::get()
{
return _pHandler;
}
} // namespace Poco
#endif // Foundation_ErrorHandler_INCLUDED

View File

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

View File

@ -0,0 +1,45 @@
//
// EventArgs.h
//
// Library: Foundation
// Package: Events
// Module: EventArgs
//
// Definition of EventArgs.
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_EventArgs_INCLUDED
#define Foundation_EventArgs_INCLUDED
#include "Poco/Foundation.h"
namespace Poco {
class Foundation_API EventArgs
/// The purpose of the EventArgs class is to be used as parameter
/// when one doesn't want to send any data.
///
/// One can use EventArgs as a base class for one's own event arguments
/// but with the arguments being a template parameter this is not
/// necessary.
{
public:
EventArgs();
virtual ~EventArgs();
};
} // namespace Poco
#endif

View File

@ -0,0 +1,56 @@
//
// EventChannel.h
//
// Library: Foundation
// Package: Logging
// Module: EventChannel
//
// Definition of the EventChannel class.
//
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_EventChannel_INCLUDED
#define Foundation_EventChannel_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Channel.h"
#include "Poco/Message.h"
#include "Poco/BasicEvent.h"
namespace Poco {
class Foundation_API EventChannel: public Channel
/// The EventChannel fires the messageLogged event for every log message
/// received. This can be used to hook custom log message processing into
/// the logging framework.
{
public:
using Ptr = AutoPtr<EventChannel>;
Poco::BasicEvent<const Message> messageLogged;
/// Fired when a message is logged by calling the log() method.
EventChannel();
/// Creates the EventChannel.
void log(const Message& msg);
/// Fires the messageLogged event.
protected:
~EventChannel();
/// Destroys the EventChannel.
};
} // namespace Poco
#endif // Foundation_EventChannel_INCLUDED

View File

@ -0,0 +1,103 @@
//
// EventLogChannel.h
//
// Library: Foundation
// Package: Logging
// Module: EventLogChannel
//
// Definition of the EventLogChannel class specific to WIN32.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_EventLogChannel_INCLUDED
#define Foundation_EventLogChannel_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Channel.h"
#include "Poco/UnWindows.h"
namespace Poco {
class Foundation_API EventLogChannel: public Channel
/// This Windows-only channel works with the Windows NT Event Log
/// service.
///
/// To work properly, the EventLogChannel class requires that either
/// the PocoFoundation.dll or the PocoMsg.dll Dynamic Link Library
/// containing the message definition resources can be found in $PATH.
{
public:
using Ptr = AutoPtr<EventLogChannel>;
EventLogChannel();
/// Creates the EventLogChannel.
/// The name of the current application (or more correctly,
/// the name of its executable) is taken as event source name.
EventLogChannel(const std::string& name);
/// Creates the EventLogChannel with the given event source name.
EventLogChannel(const std::string& name, const std::string& host);
/// Creates an EventLogChannel with the given event source
/// name that routes messages to the given host.
void open();
/// Opens the EventLogChannel. If necessary, the
/// required registry entries to register a
/// message resource DLL are made.
void close();
/// Closes the EventLogChannel.
void log(const Message& msg);
/// Logs the given message to the Windows Event Log.
///
/// The message type and priority are mapped to
/// appropriate values for Event Log type and category.
void setProperty(const std::string& name, const std::string& value);
/// Sets or changes a configuration property.
///
/// The following properties are supported:
///
/// * name: The name of the event source.
/// * loghost: The name of the host where the Event Log service is running.
/// The default is "localhost".
/// * host: same as host.
/// * logfile: The name of the log file. The default is "Application".
std::string getProperty(const std::string& name) const;
/// Returns the value of the given property.
static const std::string PROP_NAME;
static const std::string PROP_HOST;
static const std::string PROP_LOGHOST;
static const std::string PROP_LOGFILE;
protected:
~EventLogChannel();
static int getType(const Message& msg);
static int getCategory(const Message& msg);
void setUpRegistry() const;
static std::wstring findLibrary(const wchar_t* name);
private:
std::string _name;
std::string _host;
std::string _logFile;
HANDLE _h;
};
} // namespace Poco
#endif // Foundation_EventLogChannel_INCLUDED

View File

@ -0,0 +1,77 @@
//
// Event_POSIX.h
//
// Library: Foundation
// Package: Threading
// Module: Event
//
// Definition of the EventImpl class for POSIX Threads.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Event_POSIX_INCLUDED
#define Foundation_Event_POSIX_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Exception.h"
#include <pthread.h>
#include <errno.h>
namespace Poco {
class Foundation_API EventImpl
{
protected:
EventImpl(bool autoReset);
~EventImpl();
void setImpl();
void waitImpl();
bool waitImpl(long milliseconds);
void resetImpl();
private:
bool _auto;
volatile bool _state;
pthread_mutex_t _mutex;
pthread_cond_t _cond;
};
//
// inlines
//
inline void EventImpl::setImpl()
{
if (pthread_mutex_lock(&_mutex))
throw SystemException("cannot signal event (lock)");
_state = true;
if (pthread_cond_broadcast(&_cond))
{
pthread_mutex_unlock(&_mutex);
throw SystemException("cannot signal event");
}
pthread_mutex_unlock(&_mutex);
}
inline void EventImpl::resetImpl()
{
if (pthread_mutex_lock(&_mutex))
throw SystemException("cannot reset event");
_state = false;
pthread_mutex_unlock(&_mutex);
}
} // namespace Poco
#endif // Foundation_Event_POSIX_INCLUDED

View File

@ -0,0 +1,49 @@
//
// Event_VX.h
//
// Library: Foundation
// Package: Threading
// Module: Event
//
// Definition of the EventImpl class for VxWorks.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Event_VX_INCLUDED
#define Foundation_Event_VX_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Exception.h"
#include <semLib.h>
namespace Poco {
class Foundation_API EventImpl
{
protected:
EventImpl(bool autoReset);
~EventImpl();
void setImpl();
void waitImpl();
bool waitImpl(long milliseconds);
void resetImpl();
private:
bool _auto;
volatile bool _state;
SEM_ID _sem;
};
} // namespace Poco
#endif // Foundation_Event_VX_INCLUDED

View File

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

View File

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

View File

@ -0,0 +1,92 @@
//
// ExpirationDecorator.h
//
// Library: Foundation
// Package: Events
// Module: ExpirationDecorator
//
// Implementation of the ExpirationDecorator template.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ExpirationDecorator_INCLUDED
#define Foundation_ExpirationDecorator_INCLUDED
#include "Poco/Timestamp.h"
#include "Poco/Timespan.h"
namespace Poco {
template <typename TArgs>
class ExpirationDecorator
/// ExpirationDecorator adds an expiration method to values so that they can be used
/// with the UniqueExpireCache.
{
public:
ExpirationDecorator():
_value(),
_expiresAt()
{
}
ExpirationDecorator(const TArgs& p, const Poco::Timespan::TimeDiff& diffInMs):
/// Creates an element that will expire in diff milliseconds
_value(p),
_expiresAt()
{
_expiresAt += (diffInMs*1000);
}
ExpirationDecorator(const TArgs& p, const Poco::Timespan& timeSpan):
/// Creates an element that will expire after the given timeSpan
_value(p),
_expiresAt()
{
_expiresAt += timeSpan.totalMicroseconds();
}
ExpirationDecorator(const TArgs& p, const Poco::Timestamp& timeStamp):
/// Creates an element that will expire at the given time point
_value(p),
_expiresAt(timeStamp)
{
}
~ExpirationDecorator()
{
}
const Poco::Timestamp& getExpiration() const
{
return _expiresAt;
}
const TArgs& value() const
{
return _value;
}
TArgs& value()
{
return _value;
}
private:
TArgs _value;
Timestamp _expiresAt;
};
} // namespace Poco
#endif // Foundation_ExpirationDecorator_INCLUDED

View File

@ -0,0 +1,194 @@
//
// Expire.h
//
// Library: Foundation
// Package: Events
// Module: Expire
//
// Implementation of the Expire template.
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_Expire_INCLUDED
#define Foundation_Expire_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/AbstractDelegate.h"
#include "Poco/Timestamp.h"
namespace Poco {
template <class TArgs>
class Expire: public AbstractDelegate<TArgs>
/// Decorator for AbstractDelegate adding automatic
/// expiration of registrations to AbstractDelegate's.
{
public:
Expire(const AbstractDelegate<TArgs>& p, Timestamp::TimeDiff expireMillisecs):
_pDelegate(p.clone()),
_expire(expireMillisecs*1000)
{
}
Expire(const Expire& expire):
AbstractDelegate<TArgs>(expire),
_pDelegate(expire._pDelegate->clone()),
_expire(expire._expire),
_creationTime(expire._creationTime)
{
}
~Expire()
{
delete _pDelegate;
}
Expire& operator = (const Expire& expire)
{
if (&expire != this)
{
delete this->_pDelegate;
this->_pDelegate = expire._pDelegate->clone();
this->_expire = expire._expire;
this->_creationTime = expire._creationTime;
this->_pTarget = expire._pTarget;
}
return *this;
}
bool notify(const void* sender, TArgs& arguments)
{
if (!expired())
return this->_pDelegate->notify(sender, arguments);
else
return false;
}
bool equals(const AbstractDelegate<TArgs>& other) const
{
return other.equals(*_pDelegate);
}
AbstractDelegate<TArgs>* clone() const
{
return new Expire(*this);
}
void disable()
{
_pDelegate->disable();
}
const AbstractDelegate<TArgs>* unwrap() const
{
return this->_pDelegate;
}
protected:
bool expired() const
{
return _creationTime.isElapsed(_expire);
}
AbstractDelegate<TArgs>* _pDelegate;
Timestamp::TimeDiff _expire;
Timestamp _creationTime;
private:
Expire();
};
template <>
class Expire<void>: public AbstractDelegate<void>
/// Decorator for AbstractDelegate adding automatic
/// expiration of registrations to AbstractDelegate's.
{
public:
Expire(const AbstractDelegate<void>& p, Timestamp::TimeDiff expireMillisecs):
_pDelegate(p.clone()),
_expire(expireMillisecs*1000)
{
}
Expire(const Expire& expire):
AbstractDelegate<void>(expire),
_pDelegate(expire._pDelegate->clone()),
_expire(expire._expire),
_creationTime(expire._creationTime)
{
}
~Expire()
{
delete _pDelegate;
}
Expire& operator = (const Expire& expire)
{
if (&expire != this)
{
delete this->_pDelegate;
this->_pDelegate = expire._pDelegate->clone();
this->_expire = expire._expire;
this->_creationTime = expire._creationTime;
//this->_pTarget = expire._pTarget;
}
return *this;
}
bool notify(const void* sender)
{
if (!expired())
return this->_pDelegate->notify(sender);
else
return false;
}
bool equals(const AbstractDelegate<void>& other) const
{
return other.equals(*_pDelegate);
}
AbstractDelegate<void>* clone() const
{
return new Expire(*this);
}
void disable()
{
_pDelegate->disable();
}
const AbstractDelegate<void>* unwrap() const
{
return this->_pDelegate;
}
protected:
bool expired() const
{
return _creationTime.isElapsed(_expire);
}
AbstractDelegate<void>* _pDelegate;
Timestamp::TimeDiff _expire;
Timestamp _creationTime;
private:
Expire();
};
} // namespace Poco
#endif // Foundation_Expire_INCLUDED

View File

@ -0,0 +1,65 @@
//
// ExpireCache.h
//
// Library: Foundation
// Package: Cache
// Module: ExpireCache
//
// Definition of the ExpireCache class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ExpireCache_INCLUDED
#define Foundation_ExpireCache_INCLUDED
#include "Poco/AbstractCache.h"
#include "Poco/ExpireStrategy.h"
namespace Poco {
template <
class TKey,
class TValue,
class TMutex = FastMutex,
class TEventMutex = FastMutex
>
class ExpireCache: public AbstractCache<TKey, TValue, ExpireStrategy<TKey, TValue>, TMutex, TEventMutex>
/// An ExpireCache caches entries for a fixed time period (per default 10 minutes).
/// Entries expire independently of the access pattern, i.e. after a constant time.
/// If you require your objects to expire after they were not accessed for a given time
/// period use a Poco::AccessExpireCache.
///
/// Be careful when using an ExpireCache. A cache is often used
/// like cache.has(x) followed by cache.get x). Note that it could happen
/// that the "has" call works, then the current execution thread gets descheduled, time passes,
/// the entry gets invalid, thus leading to an empty SharedPtr being returned
/// when "get" is invoked.
{
public:
ExpireCache(Timestamp::TimeDiff expire = 600000):
AbstractCache<TKey, TValue, ExpireStrategy<TKey, TValue>, TMutex, TEventMutex>(ExpireStrategy<TKey, TValue>(expire))
{
}
~ExpireCache()
{
}
private:
ExpireCache(const ExpireCache& aCache);
ExpireCache& operator = (const ExpireCache& aCache);
};
} // namespace Poco
#endif // Foundation_ExpireCache_INCLUDED

View File

@ -0,0 +1,62 @@
//
// ExpireLRUCache.h
//
// Library: Foundation
// Package: Cache
// Module: ExpireLRUCache
//
// Definition of the ExpireLRUCache class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ExpireLRUCache_INCLUDED
#define Foundation_ExpireLRUCache_INCLUDED
#include "Poco/AbstractCache.h"
#include "Poco/StrategyCollection.h"
#include "Poco/ExpireStrategy.h"
#include "Poco/LRUStrategy.h"
namespace Poco {
template <
class TKey,
class TValue,
class TMutex = FastMutex,
class TEventMutex = FastMutex
>
class ExpireLRUCache: public AbstractCache<TKey, TValue, StrategyCollection<TKey, TValue>, TMutex, TEventMutex>
/// An ExpireLRUCache combines LRU caching and time based expire caching.
/// It cache entries for a fixed time period (per default 10 minutes)
/// but also limits the size of the cache (per default: 1024).
{
public:
ExpireLRUCache(std::size_t cacheSize = 1024, Timestamp::TimeDiff expire = 600000):
AbstractCache<TKey, TValue, StrategyCollection<TKey, TValue>, TMutex, TEventMutex>(StrategyCollection<TKey, TValue>())
{
this->_strategy.pushBack(new LRUStrategy<TKey, TValue>(cacheSize));
this->_strategy.pushBack(new ExpireStrategy<TKey, TValue>(expire));
}
~ExpireLRUCache()
{
}
private:
ExpireLRUCache(const ExpireLRUCache& aCache);
ExpireLRUCache& operator = (const ExpireLRUCache& aCache);
};
} // namespace Poco
#endif // Foundation_ExpireLRUCache_INCLUDED

View File

@ -0,0 +1,132 @@
//
// ExpireStrategy.h
//
// Library: Foundation
// Package: Cache
// Module: ExpireStrategy
//
// Definition of the ExpireStrategy class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ExpireStrategy_INCLUDED
#define Foundation_ExpireStrategy_INCLUDED
#include "Poco/KeyValueArgs.h"
#include "Poco/ValidArgs.h"
#include "Poco/AbstractStrategy.h"
#include "Poco/Bugcheck.h"
#include "Poco/Timestamp.h"
#include "Poco/EventArgs.h"
#include <set>
#include <map>
namespace Poco {
template <
class TKey,
class TValue
>
class ExpireStrategy: public AbstractStrategy<TKey, TValue>
/// An ExpireStrategy implements time based expiration of cache entries
{
public:
typedef std::multimap<Timestamp, TKey> TimeIndex;
typedef typename TimeIndex::iterator IndexIterator;
typedef typename TimeIndex::const_iterator ConstIndexIterator;
typedef std::map<TKey, IndexIterator> Keys;
typedef typename Keys::iterator Iterator;
public:
ExpireStrategy(Timestamp::TimeDiff expireTimeInMilliSec): _expireTime(expireTimeInMilliSec * 1000)
/// Create an expire strategy. Note that the smallest allowed caching time is 25ms.
/// Anything lower than that is not useful with current operating systems.
{
if (_expireTime < 25000) throw InvalidArgumentException("expireTime must be at least 25 ms");
}
~ExpireStrategy()
{
}
void onAdd(const void*, const KeyValueArgs <TKey, TValue>& args)
{
Timestamp now;
typename TimeIndex::value_type tiValue(now, args.key());
IndexIterator it = _keyIndex.insert(tiValue);
typename Keys::value_type kValue(args.key(), it);
std::pair<Iterator, bool> stat = _keys.insert(kValue);
if (!stat.second)
{
_keyIndex.erase(stat.first->second);
stat.first->second = it;
}
}
void onRemove(const void*, const TKey& key)
{
Iterator it = _keys.find(key);
if (it != _keys.end())
{
_keyIndex.erase(it->second);
_keys.erase(it);
}
}
void onGet(const void*, const TKey& key)
{
// get triggers no changes in an expire
}
void onClear(const void*, const EventArgs& args)
{
_keys.clear();
_keyIndex.clear();
}
void onIsValid(const void*, ValidArgs<TKey>& args)
{
Iterator it = _keys.find(args.key());
if (it != _keys.end())
{
if (it->second->first.isElapsed(_expireTime))
{
args.invalidate();
}
}
else //not found: probably removed by onReplace
args.invalidate();
}
void onReplace(const void*, std::set<TKey>& elemsToRemove)
{
// Note: replace only informs the cache which elements
// it would like to remove!
// it does not remove them on its own!
IndexIterator it = _keyIndex.begin();
while (it != _keyIndex.end() && it->first.isElapsed(_expireTime))
{
elemsToRemove.insert(it->second);
++it;
}
}
protected:
Timestamp::TimeDiff _expireTime;
Keys _keys; /// For faster replacement of keys, the iterator points to the _keyIndex map
TimeIndex _keyIndex; /// Maps time to key value
};
} // namespace Poco
#endif // Foundation_ExpireStrategy_INCLUDED

View File

@ -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 T>
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<bool> 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<bool> 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<T>& 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<T>& 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<T>& 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<T>& 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<T> _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<char> FIFOBuffer;
} // namespace Poco
#endif // Foundation_FIFOBuffer_INCLUDED

View File

@ -0,0 +1,154 @@
//
// FIFOBufferStream.h
//
// Library: Foundation
// Package: Streams
// Module: FIFOBufferStream
//
// Definition of the FIFOBufferStream class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_FIFOBufferStream_INCLUDED
#define Foundation_FIFOBufferStream_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/FIFOBuffer.h"
#include "Poco/BufferedBidirectionalStreamBuf.h"
#include <istream>
#include <ostream>
namespace Poco {
class Foundation_API FIFOBufferStreamBuf: public BufferedBidirectionalStreamBuf
/// This is the streambuf class used for reading from and writing to a FIFOBuffer.
/// FIFOBuffer is enabled for emtpy/non-empty/full state transitions notifications.
{
public:
FIFOBufferStreamBuf();
/// Creates a FIFOBufferStreamBuf.
explicit FIFOBufferStreamBuf(FIFOBuffer& fifoBuffer);
/// Creates a FIFOBufferStreamBuf and assigns the given buffer to it.
FIFOBufferStreamBuf(char* pBuffer, std::size_t length);
/// Creates a FIFOBufferStreamBuf and assigns the given buffer to it.
FIFOBufferStreamBuf(const char* pBuffer, std::size_t length);
/// Creates a FIFOBufferStreamBuf and assigns the given buffer to it.
explicit FIFOBufferStreamBuf(std::size_t length);
/// Creates a FIFOBufferStreamBuf of the given length.
~FIFOBufferStreamBuf();
/// Destroys the FIFOBufferStreamBuf.
FIFOBuffer& fifoBuffer();
/// Returns the underlying FIFO buffer reference.
protected:
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length);
private:
enum
{
STREAM_BUFFER_SIZE = 1024
};
FIFOBuffer* _pFIFOBuffer;
FIFOBuffer& _fifoBuffer;
};
class Foundation_API FIFOIOS: public virtual std::ios
/// The base class for FIFOBufferInputStream and
/// FIFOBufferStream.
///
/// This class is needed to ensure the correct initialization
/// order of the stream buffer and base classes.
{
public:
explicit FIFOIOS(FIFOBuffer& buffer);
/// Creates a FIFOIOS and assigns the given buffer to it.
FIFOIOS(char* pBuffer, std::size_t length);
/// Creates a FIFOIOS and assigns the given buffer to it.
FIFOIOS(const char* pBuffer, std::size_t length);
/// Creates a FIFOIOS and assigns the given buffer to it.
explicit FIFOIOS(std::size_t length);
/// Creates a FIFOIOS of the given length.
~FIFOIOS();
/// Destroys the FIFOIOS.
///
/// Flushes the buffer.
FIFOBufferStreamBuf* rdbuf();
/// Returns a pointer to the internal FIFOBufferStreamBuf.
void close();
/// Flushes the stream.
protected:
FIFOBufferStreamBuf _buf;
};
class Foundation_API FIFOBufferStream: public FIFOIOS, public std::iostream
/// An output stream for writing to a FIFO.
{
public:
Poco::BasicEvent<bool>& readable;
Poco::BasicEvent<bool>& writable;
explicit FIFOBufferStream(FIFOBuffer& buffer);
/// Creates the FIFOBufferStream with supplied buffer as initial value.
FIFOBufferStream(char* pBuffer, std::size_t length);
/// Creates a FIFOBufferStream and assigns the given buffer to it.
FIFOBufferStream(const char* pBuffer, std::size_t length);
/// Creates a FIFOBufferStream and assigns the given buffer to it.
explicit FIFOBufferStream(std::size_t length);
/// Creates a FIFOBufferStream of the given length.
~FIFOBufferStream();
/// Destroys the FIFOBufferStream.
///
/// Flushes the buffer.
private:
FIFOBufferStream();
FIFOBufferStream(const FIFOBufferStream& other);
FIFOBufferStream& operator =(const FIFOBufferStream& other);
};
///
/// inlines
///
inline FIFOBuffer& FIFOBufferStreamBuf::fifoBuffer()
{
return _fifoBuffer;
}
} // namespace Poco
#endif // Foundation_FIFOBufferStream_INCLUDED

View File

@ -0,0 +1,63 @@
//
// FIFOEvent.h
//
// Library: Foundation
// Package: Events
// Module: FIFOEvent
//
// Implementation of the FIFOEvent template.
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_FIFOEvent_INCLUDED
#define Foundation_FIFOEvent_INCLUDED
#include "Poco/AbstractEvent.h"
#include "Poco/FIFOStrategy.h"
#include "Poco/AbstractDelegate.h"
namespace Poco {
//@ deprecated
template <class TArgs, class TMutex = FastMutex>
class FIFOEvent: public AbstractEvent <
TArgs,
FIFOStrategy<TArgs, AbstractDelegate<TArgs>>,
AbstractDelegate<TArgs>,
TMutex
>
/// A FIFOEvent uses internally a FIFOStrategy which guarantees
/// that delegates are invoked in the order they were added to
/// the event.
///
/// Note that as of release 1.4.2, this is the default behavior
/// implemented by BasicEvent, so this class is provided
/// for backwards compatibility only.
{
public:
FIFOEvent()
{
}
~FIFOEvent()
{
}
private:
FIFOEvent(const FIFOEvent& e);
FIFOEvent& operator = (const FIFOEvent& e);
};
} // namespace Poco
#endif // Foundation_FIFOEvent_INCLUDED

View File

@ -0,0 +1,59 @@
//
// FIFOStrategy.h
//
// Library: Foundation
// Package: Events
// Module: FIFOStragegy
//
// Implementation of the FIFOStrategy template.
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_FIFOStrategy_INCLUDED
#define Foundation_FIFOStrategy_INCLUDED
#include "Poco/DefaultStrategy.h"
namespace Poco {
//@ deprecated
template <class TArgs, class TDelegate>
class FIFOStrategy: public DefaultStrategy<TArgs, TDelegate>
/// Note: As of release 1.4.2, DefaultStrategy already
/// implements FIFO behavior, so this class is provided
/// for backwards compatibility only.
{
public:
FIFOStrategy()
{
}
FIFOStrategy(const FIFOStrategy& s):
DefaultStrategy<TArgs, TDelegate>(s)
{
}
~FIFOStrategy()
{
}
FIFOStrategy& operator = (const FIFOStrategy& s)
{
DefaultStrategy<TArgs, TDelegate>::operator = (s);
return *this;
}
};
} // namespace Poco
#endif // Foundation_FIFOStrategy_INCLUDED

Some files were not shown because too many files have changed in this diff Show More