|
From: <tho...@us...> - 2012-04-30 21:05:47
|
Revision: 775
http://openautomation.svn.sourceforge.net/openautomation/?rev=775&view=rev
Author: thomas_s
Date: 2012-04-30 21:05:40 +0000 (Mon, 30 Apr 2012)
Log Message:
-----------
- added some documentation
- reworked xplcache
- almost replaced boost::posix_time with chrono
WIP
Modified Paths:
--------------
xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
xPLHAL/branches/thomas_s_dev/src/determinator.cpp
xPLHAL/branches/thomas_s_dev/src/determinator.h
xPLHAL/branches/thomas_s_dev/src/determinator_manager.h
xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
xPLHAL/branches/thomas_s_dev/src/devicemanager.h
xPLHAL/branches/thomas_s_dev/src/main.cpp
xPLHAL/branches/thomas_s_dev/src/recurring_timer.h
xPLHAL/branches/thomas_s_dev/src/xhcp.cpp
xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp
xPLHAL/branches/thomas_s_dev/src/xplcache.cpp
xPLHAL/branches/thomas_s_dev/src/xplcache.h
xPLHAL/branches/thomas_s_dev/src/xpldevice.h
xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp
Modified: xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/CMakeLists.txt 2012-04-30 21:05:40 UTC (rev 775)
@@ -21,7 +21,7 @@
file(GLOB_RECURSE Condition_sources ./conditions/*.cpp)
#set(CMAKE_CXX_FLAGS "-g -std=c++0x")
-set(CMAKE_CXX_FLAGS "-g -Os -std=c++0x")
+set(CMAKE_CXX_FLAGS "-g -O2 -std=c++0x")
set(xPLHAL_SRCS xplmessagequeue.cpp devicemanager.cpp
xplhandler.cpp xplcache.cpp xhcpthread.cpp log.cpp
xhcp.cpp xplmessage.cpp recurring_timer.cpp main.cpp pugixml.cpp
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -64,16 +64,28 @@
// cerr << "Load result: " << result.description() << "\n";
}
+/**
+ * \brief register handler for XML parser
+ * this allowes to extend the parser with more conditions
+ */
void DeterminatorXmlParser::registerCondition(BaseDeterminatorItemConstPtr condition)
{
m_conditionmap[condition->item_name] = condition;
}
+/**
+ * \brief register handler for XML parser
+ * this allowes to extend the parser with more actions
+ */
void DeterminatorXmlParser::registerAction(BaseDeterminatorItemConstPtr action)
{
m_actionmap[action->item_name] = action;
}
+/**
+ * \brief Parse the filen given in constructor
+ * \return Determinator object
+ */
Determinator DeterminatorXmlParser::parse()
{
try {
Modified: xPLHAL/branches/thomas_s_dev/src/determinator.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/determinator.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -7,6 +7,13 @@
#include <thread>
#include <future>
+/**
+ * \brief Determinator implementation.
+ *
+ * A Determinator is configured with an XML-File.
+ * When all input conditions are met (true) the Determinator is executed:
+ * All output actions are executed in the 'executeOrder' order.
+ */
class Determinator
{
public:
@@ -15,8 +22,15 @@
enum class match_type { ALL, ANY };
+ /**
+ * \brief Print Determinator in human-readable form to console
+ */
void printDeterminator() const;
+ /**
+ * \brief Check if input conditions are met, then start a thread to execute actions
+ * The output-actions are executed in a seperate thread.
+ */
void execute();
std::string guid;
@@ -38,6 +52,9 @@
typedef std::shared_ptr<Determinator> DeterminatorPtr;
typedef std::shared_ptr<const Determinator> DeterminatorConstPtr;
+/**
+ * \brief Converts a Determinator from XML to internal Object format
+ */
class DeterminatorXmlParser
{
public:
Modified: xPLHAL/branches/thomas_s_dev/src/determinator_manager.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/determinator_manager.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/determinator_manager.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -5,15 +5,23 @@
#include <boost/signals2/signal.hpp>
#include "xplhandler.h"
+/**
+ * \brief Manages Determinators in a filesystem directory
+ */
class DeterminatorManager
{
public:
DeterminatorManager(const std::string& determinatorDirectory);
+ /** \brief load Determinators from disk */
void loadDeterminators();
// DeterminatorConstPtr getDeterminator(const std::string& guid) const;
+
+ /** \brief get Determinator with GUID guid as std::string */
std::string getXmlDeterminator(const std::string& guid) const;
+
+ /** \brief store a XML-Formatted Determinator with guid on disk */
void storeXmlDeterminator(const std::string& guid, const std::string& xmlDeterminator);
public:
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -28,10 +28,6 @@
#include "devicemanager.h"
#include "i_xplcache.h"
-using boost::posix_time::ptime;
-using boost::posix_time::second_clock;
-using boost::posix_time::minutes;
-
using std::string;
using std::vector;
@@ -138,7 +134,7 @@
// A config list turned up that we haven't asked for...
// create a new device...
int interval = 5;
- ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
+ steady_time_point expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
device.VDI = source; // vendor / device / instance = unique id
device.ConfigDone = false; // false = new waiting check, true = sent/not required
device.ConfigMissing = false; // true = no config file, no response from device, false = have/waiting config
@@ -188,7 +184,7 @@
}
}
-ptime DeviceManager::calculateExpireTime(const string& string_interval, int *pInterval)
+steady_time_point DeviceManager::calculateExpireTime(const string& string_interval, int *pInterval)
{
int interval = string_interval.empty() ? atoi(string_interval.c_str()) : 5; // default to 5 minutes
if (pInterval) {
@@ -197,9 +193,9 @@
return calculateExpireTime(interval);
}
-ptime DeviceManager::calculateExpireTime(int interval)
+steady_time_point DeviceManager::calculateExpireTime(int interval)
{
- return second_clock::local_time() + minutes( 2* interval + 1 );
+ return std::chrono::steady_clock::now() + std::chrono::minutes( 2* interval + 1 );
}
void DeviceManager::processConfigHeartBeat( const xPLMessagePtr message )
@@ -212,7 +208,7 @@
// this handles a new application that identifies itself with a hbeat straight away.
// it must either be storing it's config locally, can't be configured, or is configured somewhere else.
int interval = 5;
- ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
+ steady_time_point expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
device.VDI = source; // vendor / device / instance = unique id
device.ConfigDone = false; // false = new waiting check, true = sent/not required
device.ConfigMissing = true; // true = no config file, no response from device, false = have/waiting config
@@ -254,7 +250,7 @@
// => just treat it like an heartbeat
return processConfigHeartBeat( message );
} else {
-// ptime expires = calculateExpireTime(device.Interval);
+// steady_time_point expires = calculateExpireTime(device.Interval);
// m_xPLCache->updateEntry( "config." + source + ".expires", timeConverter(calculateExpireTime(device.Interval), false ));
m_xPLCache->updateEntry( "config." + source + ".current", "true", false );
}
@@ -288,7 +284,7 @@
xPLDevice device = getDevice( source );
int interval = 5;
- ptime expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
+ steady_time_point expires = calculateExpireTime(message->getNamedValue("interval"), &interval);
writeLog( "DeviceManager::processHeartbeat("+source+") - found ["+device.VDI+"]", logLevel::debug );
if( "" == device.VDI ) {
Modified: xPLHAL/branches/thomas_s_dev/src/devicemanager.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/devicemanager.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/devicemanager.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -69,8 +69,8 @@
xPLHandler::signal_t m_sigSendXplMessage;
private:
- boost::posix_time::ptime calculateExpireTime(int interval);
- boost::posix_time::ptime calculateExpireTime(const std::string& string_interval, int *pInterval = 0);
+ steady_time_point calculateExpireTime(int interval);
+ steady_time_point calculateExpireTime(const std::string& string_interval, int *pInterval = 0);
IxPLCacheClass* m_xPLCache;
std::map<std::string, xPLDevice> mDeviceMap;
Modified: xPLHAL/branches/thomas_s_dev/src/main.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/main.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/main.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -48,6 +48,9 @@
static boost::asio::io_service* g_ioservice = nullptr;
+/**
+ * \brief Main application
+ */
class XplHalApplication
{
public:
@@ -86,6 +89,9 @@
writeLog( "main: xPL shutdown", logLevel::all );
}
+ /**
+ * \brief Installs timer while constructing
+ */
void installTimer()
{
mTimerListAllObjects.sigExpired.connect([](const boost::system::error_code& e) {
@@ -99,11 +105,18 @@
});
}
+ /**
+ * \brief quit application
+ */
static void stop()
{
m_ioservice.stop();
}
+
+ /**
+ * \brief runs the Application (called from main)
+ */
int exec()
{
// force everyone to send their configuration so that we start up to date...
Modified: xPLHAL/branches/thomas_s_dev/src/recurring_timer.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/recurring_timer.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/recurring_timer.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -20,6 +20,11 @@
#include <boost/asio.hpp>
#include <boost/signals2/signal.hpp>
+/**
+ * \brief Self-repeating timer
+ * Based on the ASIO deadline_timer which only expires once this class
+ * implements a recurring timer.
+ */
class RecurringTimer
{
public:
@@ -29,6 +34,11 @@
void start();
void stop();
+ /**
+ * \brief Expired signal to connect to
+ * This member is public to make it more easy to connect to signal.
+ * So only connect/disconnect to this signal is allowed!
+ */
boost::signals2::signal<void (const boost::system::error_code& e)> sigExpired;
private:
Modified: xPLHAL/branches/thomas_s_dev/src/xhcp.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xhcp.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xhcp.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -22,8 +22,9 @@
#include "xhcp.h"
using boost::asio::ip::tcp;
+namespace a = boost::asio;
-XHCPServer::XHCPServer(boost::asio::io_service& io, DeviceManager* dm)
+XHCPServer::XHCPServer(a::io_service& io, DeviceManager* dm)
:m_io(io)
,m_acceptor(io, tcp::endpoint(tcp::v4(), 3865))
,m_dm(dm)
Modified: xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xhcpthread.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -18,6 +18,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
+#include <ctime>
#include "globals.h"
#include "xplcache.h"
@@ -37,6 +38,8 @@
using std::string;
using std::vector;
+namespace ba = boost::asio;
+
XHCPThread::XHCPThread( socket_ptr socket, DeviceManager* dm )
: m_stoprequested(false)
, tab( "\t" )
@@ -120,11 +123,11 @@
// commands[ "SETSETTING" ] = &XHCPThread::;
commands[ "QUIT" ] = &XHCPThread::commandQuit;
- boost::asio::streambuf sb;
+ ba::streambuf sb;
boost::system::error_code error;
string greeting( "200 CHRISM-XPLHAL.SERVER1 Version 0.0 alpha XHCP 1.5 ready\r\n" );
- boost::asio::write(*sock, boost::asio::buffer(greeting));
+ ba::write(*sock, ba::buffer(greeting));
while (!quit) {
// const int TimeoutInCommand = 5 * 1000; // during transmission of an command
@@ -135,17 +138,17 @@
|| ( inMultilineRequest && endDifferent(data, "\r\n.\r\n") ) ) {
//int Timeout = (""==data) ? TimeoutExCommand : TimeoutInCommand;
- std::size_t n = boost::asio::read_until(*sock, sb, '\n');
- boost::asio::streambuf::const_buffers_type bufs = sb.data();
+ std::size_t n = ba::read_until(*sock, sb, '\n');
+ ba::streambuf::const_buffers_type bufs = sb.data();
string newData(
- boost::asio::buffers_begin(bufs),
- boost::asio::buffers_begin(bufs) + n);
+ ba::buffers_begin(bufs),
+ ba::buffers_begin(bufs) + n);
sb.consume(n);
/*
string newData;
- size_t length = sock->read_some(boost::asio::buffer(newData), error);
+ size_t length = sock->read_some(ba::buffer(newData), error);
- if (error == boost::asio::error::eof)
+ if (error == ba::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.*/
@@ -164,7 +167,7 @@
string result = (this->*multilineRequestHandler)( data );
writeLog( "Result:\n[\n" + result + "]", logLevel::debug );
//socket.write( result );
- boost::asio::write(*sock, boost::asio::buffer(result));
+ ba::write(*sock, ba::buffer(result));
}
else {
data.erase( data.size()-2 ); // chop
@@ -185,7 +188,7 @@
writeLog( "Request: [" + data + "]", logLevel::debug );
string result = (this->*command)( parameters );
writeLog( "Result:\n[\n" + result + "]", logLevel::debug );
- boost::asio::write(*sock, boost::asio::buffer(result));
+ ba::write(*sock, ba::buffer(result));
}
}
@@ -328,6 +331,16 @@
return result;
}
+template<typename D, typename F>
+std::string date2String(const D& date, const F& format)
+{
+ char tmp[50];
+ std::time_t time_ = D::clock::to_time_t(date);
+ int r = strftime(tmp, sizeof(tmp)-1, format, std::localtime(&time_));
+ tmp[r] = 0;
+ return tmp;
+}
+
string XHCPThread::commandListDevices( const string& parameter )
{
writeLog( "XHCPThread::commandListGlobals( " + parameter + " )", logLevel::debug );
@@ -345,7 +358,7 @@
if( showDevice && !device.Suspended )
{
result += device.VDI + tab;
- result += timeConverter( device.Expires ) + tab;
+ result += date2String(device.Expires, "%d.%m.%Y %H:%M:%S");
result += lexical_cast<string>( device.Interval ) + tab;
result += (device.ConfigType ? "Y" : "N") + tab;
result += (device.ConfigDone ? "Y" : "N") + tab;
Modified: xPLHAL/branches/thomas_s_dev/src/xplcache.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplcache.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xplcache.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -1,23 +1,23 @@
/*
- xPLHAL implementation in C++
- Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
+ xPLHAL implementation in C++
+ Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include <boost/algorithm/string.hpp>
-#include <boost/thread/locks.hpp>
+#include <algorithm>
#include "globals.h"
#include "log.h"
@@ -28,140 +28,146 @@
using boost::algorithm::iequals;
using boost::algorithm::is_any_of;
using boost::algorithm::split;
-using boost::posix_time::minutes;
-using boost::posix_time::second_clock;
-using boost::filesystem::path;
+namespace BFS = boost::filesystem;
+
using std::string;
using std::vector;
+using std::mutex;
+using std::lock_guard;
-timeStreamHelper timeConverter;
+//timeStreamHelper timeConverter;
+
xPLCacheClass::CacheFilter::CacheFilter() :
- prefTag( "cache" ), mfType( "*" ), mfVendor( "*" ), mfDevice( "*" ),
- mfInstance( "*" ), mfSchemType( "*" ), mfSchemClass( "*" ), expiry( false )
+ prefTag( "cache" ), mfType( "*" ), mfVendor( "*" ), mfDevice( "*" ),
+ mfInstance( "*" ), mfSchemType( "*" ), mfSchemClass( "*" ), expiry( false )
{}
xPLCacheClass::CacheFilter::CacheFilter( const string& filter ) :
- prefTag( "cache" ), expiry( false )
+ prefTag( "cache" ), expiry( false )
{
- vector<string> list;
- split( list, filter, is_any_of(".") );
- mfType = list[0];
- mfVendor = list[1];
- mfDevice = list[2];
- mfInstance = list[3];
- mfSchemType = list[4];
- mfSchemClass = list[5];
+ vector<string> list;
+ split( list, filter, is_any_of(".") );
+ mfType = list[0];
+ mfVendor = list[1];
+ mfDevice = list[2];
+ mfInstance = list[3];
+ mfSchemType = list[4];
+ mfSchemClass = list[5];
}
xPLCacheClass::xPLCacheClass()
{
- loadCache();
+ loadCache();
}
string xPLCacheClass::listAllObjects( bool forceEverything ) const
{
- writeLog( "xPLCacheClass::ListAllObjects()", logLevel::debug );
+ writeLog( "xPLCacheClass::ListAllObjects()", logLevel::debug );
- string result;
- shared_lock locker(cacheLock);
+ string result;
+ lock_guard<mutex> locker(mCachelock);
- for( cacheMap::const_iterator it = cache.begin(); it != cache.end(); it++ )
- {
- string name = it->first;
- if( starts_with( name, "device." ) )
- {
- if( forceEverything || iequals( "true", cache.find("xplhal.showdevices")->second.value ) )
- result += name + "=" + it->second.value + "\r\n";
+ for( auto &it : mCache ) {
+ string name = it.first;
+ if( starts_with( name, "device." ) ) {
+ if( forceEverything || iequals( "true", mCache.find("xplhal.showdevices")->second.value ) )
+ result += name + "=" + it.second.value + "\r\n";
+ }
+ else if( starts_with( name, "config." ) ) {
+ if( forceEverything || iequals( "true", mCache.find("xplhal.showconfigs")->second.value ) )
+ result += name + "=" + it.second.value + "\r\n";
+ }
+ else {
+ result += name + "=" + it.second.value + "\r\n";
+ }
}
- else if( starts_with( name, "config." ) )
- {
- if( forceEverything || iequals( "true", cache.find("xplhal.showconfigs")->second.value ) )
- result += name + "=" + it->second.value + "\r\n";
- }
- else
- {
- result += name + "=" + it->second.value + "\r\n";
- }
- }
- writeLog( "shared_lock locker(cacheLock): about to be destructed", logLevel::debug );
- return result;
+ writeLog( "shared_lock locker(cacheLock): about to be destructed", logLevel::debug );
+ return result;
}
void xPLCacheClass::updateEntry( const string& name, const string& value, const bool expires )
{
- writeLog( "xPLCacheClass::updateEntry( \"" + name + "\", \"" + value + "\" )", logLevel::debug );
- unique_lock locker(cacheLock);
+ writeLog( "xPLCacheClass::updateEntry( \"" + name + "\", \"" + value + "\" )", logLevel::debug );
+ lock_guard<mutex> locker(mCachelock);
- cacheMap::iterator it = cache.find( name );
- if( cache.end() == it )
- cache.insert( std::pair<string,CacheEntry>( name, CacheEntry( value, expires ) ) );
- else
- it->second = CacheEntry( value, expires );
+ auto it = mCache.find( name );
+ if( mCache.end() == it ) {
+ mCache.insert({name, CacheEntry( value, expires )});
+ }
+ else {
+ it->second = CacheEntry( value, expires );
+ }
}
void xPLCacheClass::deleteEntry( const string& name )
{
- writeLog( "xPLCacheClass::deleteEntry( \"" + name + "\" )", logLevel::debug );
- unique_lock locker(cacheLock);
- cache.erase( name );
+ writeLog( "xPLCacheClass::deleteEntry( \"" + name + "\" )", logLevel::debug );
+ lock_guard<mutex> locker(mCachelock);
+ mCache.erase( name );
}
+template<typename Map, typename F>
+void map_erase_if(Map& m, F pred)
+{
+ for (typename Map::iterator i = m.begin();
+ (i = std::find_if(i, m.end(), pred)) != m.end();
+ m.erase(i++));
+}
+
void xPLCacheClass::flushExpiredEntries( void )
{
- writeLog( "xPLCacheClass::flushExpiredEntries()", logLevel::debug );
- unique_lock locker(cacheLock);
- for( cacheMap::iterator it = cache.begin(); it != cache.end(); )
- {
- // delete if entry is older than 15 minutes
- if( it->second.expiry && (it->second.date < second_clock::local_time() - minutes( 15 )) )
- cache.erase( it++ );
- else
- ++it;
- }
+ writeLog( "xPLCacheClass::flushExpiredEntries()", logLevel::debug );
+ lock_guard<mutex> locker(mCachelock);
+
+ map_erase_if(mCache, [](cachemap_t::value_type &cache) {
+ return cache.second.isExpired();
+ });
}
vector<string> xPLCacheClass::childNodes( const string& filter ) const
{
- vector<string> retval;
+ vector<string> retval;
- for( cacheMap::const_iterator it = cache.begin(); it != cache.end(); ++it )
- if( starts_with( it->first, filter ) )
- retval.push_back( it->first );
+ for(auto &it : mCache) {
+ if( starts_with( it.first, filter ) ) {
+ retval.push_back( it.first );
+ }
+ }
- return retval;
+ return retval;
}
vector<string> xPLCacheClass::filterByRegEx( const boost::regex& regex ) const
{
- vector<string> retval;
+ vector<string> retval;
- for( cacheMap::const_iterator it = cache.begin(); it != cache.end(); ++it )
- {
- if( boost::regex_match( it->first, regex ) )
- retval.push_back( it->first );
- }
+ for(auto &it : mCache) {
+ if( boost::regex_match( it.first, regex ) ) {
+ retval.push_back( it.first );
+ }
+ }
- return retval;
+ return retval;
}
void xPLCacheClass::loadCache( void )
{
- cache.clear(); // erase all entries
+ mCache.clear(); // erase all entries
- path objectCacheFile( DataFileFolder / "object_cache.xml" );
- writeLog( "loadCache: ["+objectCacheFile.string()+"]", logLevel::debug );
- if( boost::filesystem::exists( objectCacheFile ) )
- {
- writeLog( "Loading cached xPL object from file: "+objectCacheFile.string(), logLevel::debug );
- } else {
- writeLog( "No xPL object cache file found at: "+objectCacheFile.string()+" - creating a new one...", logLevel::debug );
- updateEntry( "xplhal.period" , "0" , false );
- updateEntry( "xplhal.mode" , "0" , false );
- updateEntry( "xplhal.showdevices", "true", false );
- updateEntry( "xplhal.showconfigs", "true", false );
- }
+ BFS::path objectCacheFile( DataFileFolder / "object_mCache.xml" );
+ writeLog( "loadCache: ["+objectCacheFile.string()+"]", logLevel::debug );
+ if( BFS::exists( objectCacheFile ) ) {
+ writeLog( "Loading cached xPL object from file: "+objectCacheFile.string(), logLevel::debug );
+ }
+ else {
+ writeLog( "No xPL object cache file found at: "+objectCacheFile.string()+" - creating a new one...", logLevel::debug );
+ updateEntry( "xplhal.period" , "0" , false );
+ updateEntry( "xplhal.mode" , "0" , false );
+ updateEntry( "xplhal.showdevices", "true", false );
+ updateEntry( "xplhal.showconfigs", "true", false );
+ }
}
void xPLCacheClass::saveCache( void ) const
Modified: xPLHAL/branches/thomas_s_dev/src/xplcache.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xplcache.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xplcache.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -1,61 +1,35 @@
#pragma once
/*
- xPLHAL implementation in C++
- Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
+ xPLHAL implementation in C++
+ Copyright (C) 2009 by Christian Mayer - xpl at ChristianMayer dot de
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include <string>
#include <vector>
#include <map>
+#include <chrono>
+#include <thread>
-#include <boost/thread/shared_mutex.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/regex.hpp>
#include "i_xplcache.h"
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#define steady_clock monotonic_clock
+#endif
-/** Helper function */
-class timeStreamHelper
-{
- std::stringstream timeStream;
- public:
- timeStreamHelper()
- {
- boost::posix_time::time_facet* output_facet = new boost::posix_time::time_facet( "%d.%m.%Y %H:%M:%S" );
- timeStream.imbue(std::locale(timeStream.getloc(), output_facet));
- boost::posix_time::time_input_facet* input_facet = new boost::posix_time::time_input_facet( "%d.%m.%Y %H:%M:%S" );
- timeStream.imbue(std::locale(timeStream.getloc(), input_facet));
- }
- std::string operator()( const boost::posix_time::ptime& time )
- {
- timeStream.str("");
- timeStream << time;
- return timeStream.str();
- }
- boost::posix_time::ptime operator()( const std::string& time )
- {
- boost::posix_time::ptime retval;
- timeStream.str("");
- timeStream << time;
- timeStream >> retval;
- return retval;
- }
-};
-extern timeStreamHelper timeConverter;
-
/**
* \class xPLCacheClass
*
@@ -65,91 +39,106 @@
*/
class xPLCacheClass: public IxPLCacheClass
{
- protected:
- /**
- * \brief Representation of a xPL value in the cache.
- */
- struct CacheEntry
- {
- std::string value; /**< \brief Value of the xPL message. */
- boost::posix_time::ptime date; /**< \brief Timestamp of time of entry. */
- bool expiry; /**< \brief Flag if this entry should expire. */
+ protected:
+ /**
+ * \brief Representation of a xPL value in the cache.
+ */
+ struct CacheEntry
+ {
+ //! \brief Value of the xPL message.
+ std::string value;
+
+ //! \brief Timestamp of time of entry.
+ std::chrono::time_point<std::chrono::steady_clock> mDate;
- /** \brief Construct the entry with a current timestamp. */
- CacheEntry( const std::string& v, bool expires ) : value( v ), date( boost::posix_time::second_clock::local_time() ), expiry( expires ) {}
- };
+ //! \brief Flag if this entry should expire.
+ bool expiry;
- /** \brief Link a QString as the name to the corresponding value in
- * the CacheEntry with fast lookup. */
- typedef std::map< std::string, CacheEntry > cacheMap;
- cacheMap cache; /**< \brief The cache itself. */
+ //! \brief Construct the entry with a current timestamp.
+ CacheEntry( const std::string& v, bool expires ) : value( v ), mDate(std::chrono::steady_clock::now()), expiry( expires ) {}
- /** \brief variable to lock write operations on the cache for safe
- * multithreading operation. */
- mutable boost::shared_mutex cacheLock;
- typedef boost::shared_lock<boost::shared_mutex> shared_lock;
- typedef boost::unique_lock<boost::shared_mutex> unique_lock;
+ bool isExpired() const {
+ return expiry && mDate < (std::chrono::steady_clock::now() - std::chrono::minutes(15));
+ }
+
+ };
- /**
- * \brief Representation of an xPL filter.
- */
- struct CacheFilter
- {
- std::string prefTag;
- std::string mfType;
- std::string mfVendor;
- std::string mfDevice;
- std::string mfInstance;
- std::string mfSchemType;
- std::string mfSchemClass;
- bool expiry;
+ /** \brief Link a QString as the name to the corresponding value in
+ * the CacheEntry with fast lookup. */
+ typedef std::map< std::string, CacheEntry > cachemap_t;
+ cachemap_t mCache; /**< \brief The cache itself. */
- CacheFilter();
- CacheFilter( const std::string& filter );
+ /** \brief variable to lock write operations on the cache for safe
+ * multithreading operation. */
+ mutable std::mutex mCachelock;
- /** \returns the xPL filter. */
- std::string xPLFilter( void ) const
- {
- return mfType + "." + mfVendor + "." + mfDevice + "." + mfInstance + "." + mfSchemType + "." + mfSchemClass;
- }
- };
+ /**
+ * \brief Representation of an xPL filter.
+ */
+ struct CacheFilter
+ {
+ std::string prefTag;
+ std::string mfType;
+ std::string mfVendor;
+ std::string mfDevice;
+ std::string mfInstance;
+ std::string mfSchemType;
+ std::string mfSchemClass;
+ bool expiry;
- public:
- xPLCacheClass();
+ CacheFilter();
+ CacheFilter( const std::string& filter );
- /** \returns true if the element name exists. */
- bool exists( const std::string& name ) const
- { return cache.end() != cache.find( name ); }
+ /** \returns the xPL filter. */
+ std::string xPLFilter( void ) const
+ {
+ return mfType + "." + mfVendor + "." + mfDevice + "." + mfInstance + "." + mfSchemType + "." + mfSchemClass;
+ }
+ };
- /** \returns the value of element name if it exists - or an empty std::string otherwise. */
- std::string objectValue( const std::string& name ) const
- { cacheMap::const_iterator it = cache.find( name ); if( cache.end() == it ) return std::string(); else return it->second.value; }
+ public:
+ xPLCacheClass();
- /** \returns all objectes stored in the cache. */
- std::string listAllObjects( bool forceEverything = false ) const;
+ /** \returns true if the element name exists. */
+ bool exists( const std::string& name ) const {
+ return mCache.end() != mCache.find( name );
+ }
- /** \brief Create a new object or update it if it exists in the cache. */
- void updateEntry( const std::string& name, const std::string& value, const bool expires = true );
+ /** \returns the value of element name if it exists - or an empty std::string otherwise. */
+ std::string objectValue( const std::string& name ) const {
+ auto it = mCache.find( name );
+ if( mCache.end() == it )
+ return std::string();
+ else
+ return it->second.value;
+ }
- /** \brief Delete an object if it exists in the cache - or do nothing. */
- void deleteEntry( const std::string& name );
+ /** \returns all objectes stored in the cache. */
+ std::string listAllObjects( bool forceEverything = false ) const;
- /** \brief Delete all expired entries. */
- void flushExpiredEntries( void );
+ /** \brief Create a new object or update it if it exists in the cache. */
+ void updateEntry( const std::string& name, const std::string& value, const bool expires = true );
- /** \returns all entries that start with filter. */
- std::vector<std::string> childNodes( const std::string& filter ) const;
+ /** \brief Delete an object if it exists in the cache - or do nothing. */
+ void deleteEntry( const std::string& name );
- /** \returns all entries that fit the regular expression. */
- std::vector<std::string> filterByRegEx( const boost::regex& regex ) const;
+ /** \brief Delete all expired entries. */
+ void flushExpiredEntries( void );
- /** \returns all entries that fit the regular expression. */
- std::vector<std::string> filterByRegEx( const std::string& regex ) const
- { return filterByRegEx( boost::regex( regex ) ); }
+ /** \returns all entries that start with filter. */
+ std::vector<std::string> childNodes( const std::string& filter ) const;
- /** \brief Load object cache from file system */
- void loadCache( void );
+ /** \returns all entries that fit the regular expression. */
+ std::vector<std::string> filterByRegEx( const boost::regex& regex ) const;
- /** \brief Save object cache to file system */
- void saveCache( void ) const;
+ /** \returns all entries that fit the regular expression. */
+ std::vector<std::string> filterByRegEx( const std::string& regex ) const {
+ return filterByRegEx( boost::regex( regex ) );
+ }
+
+ /** \brief Load object cache from file system */
+ void loadCache( void );
+
+ /** \brief Save object cache to file system */
+ void saveCache( void ) const;
};
Modified: xPLHAL/branches/thomas_s_dev/src/xpldevice.h
===================================================================
--- xPLHAL/branches/thomas_s_dev/src/xpldevice.h 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/src/xpldevice.h 2012-04-30 21:05:40 UTC (rev 775)
@@ -18,19 +18,21 @@
*/
#include <string>
-#include <boost/date_time/posix_time/posix_time.hpp>
+#include <chrono>
+typedef std::chrono::time_point<std::chrono::steady_clock> steady_time_point;
+
struct xPLDevice
{
- std::string VDI; /** \brief vendor / device / instance = unique id */
- boost::posix_time::ptime Expires; /** \brief time expires */
- int Interval; /** \brief current heartbeat interval */
- bool ConfigType; /** \brief true = config. false = hbeat. */
- bool ConfigDone; /** \brief false = new waiting check, true = sent/not required */
- bool WaitingConfig; /** \brief false = waiting check or not needed, true = manual intervention */
- bool ConfigListSent; /** \brief Have we asked this device for it's config? */
- std::string ConfigSource; /** \brief v-d.xml / v-d.cache.xml or empty */
- bool ConfigMissing; /** \brief true = no config file, no response from device, false = have/waiting config */
- bool Suspended; /** \brief lost heartbeat */
- bool Current; /** \brief asked for current */
+ std::string VDI; //! \brief vendor / device / instance = unique id
+ steady_time_point Expires; //! \brief time expires
+ int Interval; //! \brief current heartbeat interval
+ bool ConfigType; //! \brief true = config. false = hbeat.
+ bool ConfigDone; //! \brief false = new waiting check, true = sent/not required
+ bool WaitingConfig; //! \brief false = waiting check or not needed, true = manual intervention
+ bool ConfigListSent; //! \brief Have we asked this device for it's config?
+ std::string ConfigSource; //! \brief v-d.xml / v-d.cache.xml or empty
+ bool ConfigMissing; //! \brief true = no config file, no response from device, false = have/waiting config */
+ bool Suspended; //! \brief lost heartbeat
+ bool Current; //! \brief asked for current
};
Modified: xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp
===================================================================
--- xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp 2012-04-30 16:51:48 UTC (rev 774)
+++ xPLHAL/branches/thomas_s_dev/test/test_devicemanager.cpp 2012-04-30 21:05:40 UTC (rev 775)
@@ -9,6 +9,7 @@
#include "devicemanager.h"
#include <boost/regex.hpp>
+#include <iostream>
xPLMessagePtr createXplMessage(xPL_MessageType type, const std::string& srcVDI, const std::string& dstVDI,
const std::string& msgClass, const std::string& msgType, xPLMessage::namedValueList list)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|