///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::PassiveConnector
+prefix_ senf::ppi::connector::ActiveConnector & senf::ppi::connector::PassiveConnector::peer()
+ const
+{
+ return dynamic_cast<ActiveConnector&>(Connector::peer());
+}
+
prefix_ bool senf::ppi::connector::PassiveConnector::throttled()
const
{
return nativeThrottled_ || remoteThrottled_;
}
+////////////////////////////////////////
+// private members
+
+prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle()
+{
+ peer().notifyThrottle();
+}
+
+prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle()
+{
+ peer().notifyUnthrottle();
+ v_unthrottleEvent();
+}
+
+prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle()
+{
+ if (!throttled()) {
+ remoteThrottled_ = true;
+ emitThrottle();
+ }
+ else
+ remoteThrottled_ = true;
+}
+
+prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
+{}
+
+prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route)
+{
+ routes_.push_back(&route);
+}
+
+// public members
+
prefix_ bool senf::ppi::connector::PassiveConnector::nativeThrottled()
const
{
}
-prefix_ senf::ppi::connector::ActiveConnector & senf::ppi::connector::PassiveConnector::peer()
- const
-{
- return dynamic_cast<ActiveConnector&>(Connector::peer());
-}
-
////////////////////////////////////////
// protected members
callback_();
}
-////////////////////////////////////////
-// private members
-
-prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle()
-{
- if (!throttled()) {
- remoteThrottled_ = true;
- emitThrottle();
- }
- else
- remoteThrottled_ = true;
-}
-
-prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle()
-{
- peer().notifyThrottle();
-}
-
-prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle()
-{
- peer().notifyUnthrottle();
- v_unthrottleEvent();
-}
-
-prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
-{}
-
-prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route)
-{
- routes_.push_back(&route);
-}
-
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::ActiveConnector
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::OutputConnector
+prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConnector::peer()
+ const
+{
+ return dynamic_cast<InputConnector&>(Connector::peer());
+}
+
prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet p)
{
peer().enqueue(p);
operator()(p);
}
-prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConnector::peer()
- const
-{
- return dynamic_cast<InputConnector&>(Connector::peer());
-}
-
////////////////////////////////////////
// protected members
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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 2 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief DebugModules non-inline non-template implementation */
+
+#include "DebugModules.hh"
+//#include "DebugModules.ih"
+
+// Custom includes
+
+//#include "DebugModules.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::ppi::module::debug::PassiveSource
+
+prefix_ void senf::ppi::module::debug::PassiveSource::request()
+{
+ SENF_ASSERT( ! packets_.empty() );
+ output(packets_.front());
+ packets_.pop_front();
+ if (packets_.empty())
+ output.throttle();
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::ppi::module::debug::PassiveSink
+
+prefix_ void senf::ppi::module::debug::PassiveSink::request()
+{
+ packets_.push_back(input());
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "DebugModules.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
////////////////////////////////////////
// private members
-prefix_ void senf::ppi::module::debug::PassiveSource::request()
-{
- SENF_ASSERT( ! packets_.empty() );
- output(packets_.front());
- packets_.pop_front();
- if (packets_.empty())
- output.throttle();
-}
-
prefix_ void senf::ppi::module::debug::PassiveSource::init()
{
if (empty())
packets_.erase(packets_.begin(), packets_.end());
}
-////////////////////////////////////////
-// private members
-
-prefix_ void senf::ppi::module::debug::PassiveSink::request()
-{
- packets_.push_back(input());
-}
-
///////////////////////////////////////////////////////////////////////////
// senf::ppi::module::debug::ActiveFeederSource
///////////////////////////////////////////////////////////////////////////
// senf::ppi::module::Module
+////////////////////////////////////////
+// private members
+
+prefix_ void senf::ppi::module::Module::init()
+{}
+
+prefix_ senf::ppi::EventManager & senf::ppi::module::Module::eventManager()
+ const
+{
+ return EventManager::instance();
+}
+
+prefix_ senf::ppi::ModuleManager & senf::ppi::module::Module::moduleManager()
+ const
+{
+ return ModuleManager::instance();
+}
+
+prefix_ void senf::ppi::module::Module::registerConnector(connector::Connector & connector)
+{
+ connectorRegistry_.push_back(&connector);
+ connector.setModule(*this);
+}
+
+prefix_ senf::ppi::RouteBase &
+senf::ppi::module::Module::addRoute(std::auto_ptr<RouteBase> route)
+{
+ routes_.push_back(route.release());
+ return routes_.back();
+}
+
+////////////////////////////////////////
+// public members
+
prefix_ senf::ppi::module::Module::~Module()
{
moduleManager().unregisterModule(*this);
eventManager().destroyModule(*this);
}
-////////////////////////////////////////
-// private members
-
-prefix_ void senf::ppi::module::Module::init()
-{}
-
-prefix_ senf::ppi::EventManager & senf::ppi::module::Module::eventManager()
- const
-{
- return EventManager::instance();
-}
-
-prefix_ senf::ppi::ModuleManager & senf::ppi::module::Module::moduleManager()
- const
-{
- return ModuleManager::instance();
-}
-
-prefix_ void senf::ppi::module::Module::registerConnector(connector::Connector & connector)
-{
- connectorRegistry_.push_back(&connector);
- connector.setModule(*this);
-}
-
-prefix_ senf::ppi::RouteBase &
-senf::ppi::module::Module::addRoute(std::auto_ptr<RouteBase> route)
-{
- routes_.push_back(route.release());
- return routes_.back();
-}
-
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
///////////////////////////////////////////////////////////////////////////
// senf::Packet
+// protected members
+
+prefix_ senf::Packet::Packet(PacketInterpreterBase::ptr packet)
+ : packet_(packet)
+{}
+
+prefix_ senf::PacketInterpreterBase::ptr senf::Packet::ptr()
+ const
+{
+ SENF_ASSERT(packet_);
+ return packet_;
+}
+
// public structors
prefix_ senf::Packet::Packet()
{}
+// public members
+
prefix_ senf::Packet senf::Packet::clone()
const
{
// Interpreter chain access
+prefix_ senf::Packet senf::Packet::next(NoThrow_t)
+ const
+{
+ PacketInterpreterBase::ptr p (ptr()->next());
+ return !p && ptr()->nextPacketRange() ? checkNext() : Packet(p);
+}
+
prefix_ senf::Packet senf::Packet::next()
const
{
return p;
}
-prefix_ senf::Packet senf::Packet::next(NoThrow_t)
+prefix_ senf::Packet senf::Packet::prev(NoThrow_t)
const
{
- PacketInterpreterBase::ptr p (ptr()->next());
- return !p && ptr()->nextPacketRange() ? checkNext() : Packet(p);
+ return Packet(ptr()->prev());
}
prefix_ senf::Packet senf::Packet::prev()
return p;
}
-prefix_ senf::Packet senf::Packet::prev(NoThrow_t)
- const
-{
- return Packet(ptr()->prev());
-}
-
prefix_ senf::Packet senf::Packet::first()
const
{
return packet_ && packet_->valid();
}
-// protected members
-
-prefix_ senf::Packet::Packet(PacketInterpreterBase::ptr packet)
- : packet_(packet)
-{}
-
-prefix_ senf::PacketInterpreterBase::ptr senf::Packet::ptr()
- const
-{
- SENF_ASSERT(packet_);
- return packet_;
-}
-
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
#include "../Utils/senfassert.hh"
#include <iterator>
#include "PacketImpl.hh"
-#include "PacketParser.hh"
+// #include "PacketParser.hh"
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::PacketData
+prefix_ senf::detail::PacketImpl & senf::PacketData::impl()
+ const
+{
+ SENF_ASSERT( impl_ );
+ return *impl_;
+}
+
prefix_ senf::PacketData::iterator senf::PacketData::begin()
const
{
: impl_(), begin_(b), end_(e)
{}
-prefix_ senf::detail::PacketImpl & senf::PacketData::impl()
- const
-{
- SENF_ASSERT( impl_ );
- return *impl_;
-}
-
-///////////////////////////////////////////////////////////////////////////
-// senf::safe_data_iterator
-
-prefix_ senf::safe_data_iterator::safe_data_iterator()
- : data_(0), i_(0)
-{}
-
-prefix_ senf::safe_data_iterator::safe_data_iterator(PacketData & data)
- : data_(&data), i_(0)
-{}
-
-prefix_ senf::safe_data_iterator::safe_data_iterator(PacketData & data, PacketData::iterator i)
- : data_(&data), i_(std::distance(data.begin(),i))
-{}
-
-prefix_ senf::safe_data_iterator::safe_data_iterator(PacketParserBase const & parser)
- : data_(&parser.data()), i_(std::distance(data_->begin(),parser.i()))
-{}
-
-prefix_ senf::safe_data_iterator & senf::safe_data_iterator::operator=(PacketData::iterator i)
-{
- SENF_ASSERT(data_);
- i_ = std::distance(data_->begin(),i);
- return *this;
-}
-
-prefix_ senf::safe_data_iterator &
-senf::safe_data_iterator::operator=(PacketParserBase const & parser)
-{
- data_ = &parser.data();
- i_ = std::distance(data_->begin(),parser.i());
- return *this;
-}
-
-prefix_ senf::safe_data_iterator::operator senf::PacketData::iterator()
- const
-{
- return i();
-}
-
-prefix_ bool senf::safe_data_iterator::boolean_test()
- const
-{
- return data_;
-}
-
-prefix_ senf::PacketData & senf::safe_data_iterator::data()
- const
-{
- SENF_ASSERT(data_);
- return *data_;
-}
-
-prefix_ senf::safe_data_iterator::value_type & senf::safe_data_iterator::dereference()
- const
-{
- return *i();
-}
-
-prefix_ bool senf::safe_data_iterator::equal(safe_data_iterator const & other)
- const
-{
- SENF_ASSERT(data_ == other.data_);
- return i_ == other.i_;
-}
-
-prefix_ senf::safe_data_iterator::difference_type
-senf::safe_data_iterator::distance_to(safe_data_iterator const & other)
- const
-{
- SENF_ASSERT(data_ == other.data_);
- return other.i_ - i_;
-}
-
-prefix_ void senf::safe_data_iterator::increment()
-{
- ++i_;
-}
-
-prefix_ void senf::safe_data_iterator::decrement()
-{
- SENF_ASSERT(i_>0);
- --i_;
-}
-
-prefix_ void senf::safe_data_iterator::advance(difference_type n)
-{
- SENF_ASSERT( -n < difference_type(i_) );
- i_ += n;
-}
-
-prefix_ senf::PacketData::iterator senf::safe_data_iterator::i()
- const
-{
- SENF_ASSERT(data_);
- return boost::next(data_->begin(),i_);
-}
-
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
// Custom includes
#include <boost/utility.hpp>
#include <boost/type_traits.hpp>
-#include <boost/iterator/iterator_facade.hpp>
#include "../Utils/safe_bool.hh"
#include "../Utils/Exception.hh"
#include "PacketTypes.hh"
struct TruncatedPacketException : public senf::Exception
{ TruncatedPacketException() : senf::Exception("truncated packet"){} };
- /** \brief Re-validating data iterator
-
- This class is a wrapper around a PacketData::iterator instance. It will revalidate the
- iterator on every access. This keeps the iterator valid even when the data container is
- resized and thereby possibly relocated. The iterator will always point to the byte at the
- same offset from the packets beginning. If data is inserted before this iterators position,
- the data pointed to will of course change.
-
- For this to work, the safe_data_iterator must be initialized with the container to which the
- iterator belongs. After this initialization it can be used like any other iterator.
- */
- class safe_data_iterator
- : public boost::iterator_facade< safe_data_iterator,
- PacketData::value_type,
- boost::random_access_traversal_tag >,
- public comparable_safe_bool<safe_data_iterator>
- {
- public:
- typedef PacketData::size_type size_type;
-
- safe_data_iterator(); ///< Make uninitialized iterator
- explicit safe_data_iterator(PacketData & data);
- ///< Construct iterator only setting the data container
- safe_data_iterator(PacketData & data, PacketData::iterator i);
- ///< Initialize iterator to given position
- explicit safe_data_iterator(PacketParserBase const & parser);
- ///< Initialize iterator from parser
- /**< The iterator will point to the parsers start
- position. */
-
- safe_data_iterator & operator=(PacketData::iterator i); ///< Assign iterator
- /**< The iteator \a i must be from the container wo which \c
- this iterator has been initialized. */
- safe_data_iterator & operator=(PacketParserBase const & parser);
- ///< Assign iterator from parser
- /**< The iterator will point to the parser start
- position. */
-
- operator PacketData::iterator() const; ///< Convert to iterator
-
- bool boolean_test() const; ///< Check, if iterator is initialized
-
- PacketData & data() const; ///< Access data container
-
- private:
- friend class boost::iterator_core_access;
-
- // iterator_facade interface
-
- value_type & dereference() const;
- bool equal(safe_data_iterator const & other) const;
- difference_type distance_to(safe_data_iterator const & other) const;
- void increment();
- void decrement();
- void advance(difference_type n);
-
- PacketData::iterator i() const;
-
- PacketData * data_;
- size_type i_;
- };
}
///////////////////////////////hh.e////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::detail::PacketImpl
+// This function has a problem being inlined. Somehow, often when calling this, the size of the
+// resulting inlined code would be huge. Need to further debug this.
+
+prefix_ void senf::detail::PacketImpl::release(refcount_t n)
+{
+ SENF_ASSERT(refcount_ >= n);
+ // uah ... we need to be extremely careful here. If refcount_ is n, we want to commit suicide,
+ // however the destructor will remove all PacketInterpreters from the list and will thereby
+ // decrement refcount -> only decrenebt refcount_ when *not* caling delete
+ if (refcount_ == n)
+ delete this;
+ else
+ refcount_ -= n;
+}
+
// interpreter chain
prefix_ void senf::detail::PacketImpl::appendInterpreter(PacketInterpreterBase * p)
// Custom includes
#include "../Utils/senfassert.hh"
-#include "PacketInterpreter.hh"
+// #include "PacketInterpreter.hh"
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
refcount_ += n;
}
-prefix_ void senf::detail::PacketImpl::release(refcount_t n)
-{
- SENF_ASSERT(refcount_ >= n);
- // uah ... we need to be extremely careful here. If refcount_ is n, we want to commit suicide,
- // however the destructor will remove all PacketInterpreters from the list and will thereby
- // decrement refcount -> only decrenebt refcount_ when *not* caling delete
- if (refcount_ == n)
- delete this;
- else
- refcount_ -= n;
-}
-
prefix_ senf::detail::PacketImpl::refcount_t senf::detail::PacketImpl::refcount()
const
{
///////////////////////////////////////////////////////////////////////////
// senf::PacketParserBase
+// public members
+
prefix_ senf::PacketParserBase::data_iterator senf::PacketParserBase::i()
const
{
return i_;
}
-prefix_ senf::PacketParserBase::data_iterator senf::PacketParserBase::i(size_type offset)
- const
-{
- validate(offset);
- return boost::next(i_, offset);
-}
+// private members
-prefix_ senf::PacketParserBase::state_type senf::PacketParserBase::state()
+prefix_ senf::PacketParserBase::data_iterator senf::PacketParserBase::end()
const
{
- return data_;
+ return data_->end();
}
-prefix_ senf::PacketData & senf::PacketParserBase::data()
+// protected members
+
+prefix_ bool senf::PacketParserBase::check(size_type size)
const
{
- return * data_;
+ return size <= size_type(std::distance(i(),end()));
}
-prefix_ void senf::PacketParserBase::init()
- const
-{}
-
-prefix_ void senf::PacketParserBase::defaultInit()
- const
-{}
-
-prefix_ senf::Packet senf::PacketParserBase::packet()
- const
+prefix_ void senf::PacketParserBase::validate(size_type size)
+ const
{
- // OUCH ... I hate this but for some awkward packet types, access to the packet
- // from the parser is really needed (e.g. UDP when building the pseudo-header
- // for calculating the checksum).
- return Packet(PacketInterpreterBase::ptr(static_cast<PacketInterpreterBase*>(&data())));
+ if (! check(size))
+ throw TruncatedPacketException();
}
-////////////////////////////////////////
-// protected members
-
prefix_ senf::PacketParserBase::PacketParserBase(data_iterator i, state_type s)
: i_ (i), data_ (s)
{}
validate(size);
}
-prefix_ bool senf::PacketParserBase::check(size_type size)
+// public members
+
+prefix_ senf::PacketParserBase::data_iterator senf::PacketParserBase::i(size_type offset)
const
{
- return size <= size_type(std::distance(i(),end()));
+ validate(offset);
+ return boost::next(i_, offset);
}
-prefix_ void senf::PacketParserBase::validate(size_type size)
+prefix_ senf::PacketParserBase::state_type senf::PacketParserBase::state()
const
{
- if (! check(size))
- throw TruncatedPacketException();
+ return data_;
}
-////////////////////////////////////////
-// private members
+prefix_ senf::PacketData & senf::PacketParserBase::data()
+ const
+{
+ return * data_;
+}
-prefix_ senf::PacketParserBase::data_iterator senf::PacketParserBase::end()
+prefix_ void senf::PacketParserBase::init()
+ const
+{}
+
+prefix_ void senf::PacketParserBase::defaultInit()
+ const
+{}
+
+prefix_ senf::Packet senf::PacketParserBase::packet()
const
{
- return data_->end();
+ // OUCH ... I hate this but for some awkward packet types, access to the packet
+ // from the parser is really needed (e.g. UDP when building the pseudo-header
+ // for calculating the checksum).
+ return Packet(PacketInterpreterBase::ptr(static_cast<PacketInterpreterBase*>(&data())));
}
///////////////////////////////cci.e///////////////////////////////////////
{}
#endif
+// Why is this function reported as not inlineable ?
+
+template <class Parser>
+prefix_ senf::PacketParserBase::size_type senf::detail::packetParserSize(Parser p, ...)
+{
+ return p.bytes();
+}
+
///////////////////////////////ct.e////////////////////////////////////////
#undef prefix_
return Parser::fixed_bytes;
}
-template <class Parser>
-prefix_ senf::PacketParserBase::size_type senf::detail::packetParserSize(Parser p, ...)
-{
- return p.bytes();
-}
-
-///////////////////////////////////////////////////////////////////////////
-// senf::SafePacketParserWrapper<Parser>
-
-template <class Parser>
-prefix_ senf::SafePacketParserWrapper<Parser>::SafePacketParserWrapper()
- : parser_(), i_()
-{}
-
-template <class Parser>
-prefix_ senf::SafePacketParserWrapper<Parser>::SafePacketParserWrapper(Parser parser)
- : parser_(parser), i_(parser)
-{}
-
-template <class Parser>
-prefix_ senf::SafePacketParserWrapper<Parser> & senf::SafePacketParserWrapper<Parser>::operator=(Parser parser)
-{
- parser_ = parser;
- i_ = parser;
- return *this;
-}
-
-template <class Parser>
-prefix_ Parser senf::SafePacketParserWrapper<Parser>::operator*()
- const
-{
- SENF_ASSERT( i_ );
- parser_->i_ = PacketParserBase::data_iterator(i_);
- return *parser_;
-}
-
-template <class Parser>
-prefix_ Parser const * senf::SafePacketParserWrapper<Parser>::operator->()
- const
-{
- SENF_ASSERT( i_ );
- parser_->i_ = PacketParserBase::data_iterator(i_);
- return & (*parser_);
-}
-
-template <class Parser>
-prefix_ bool senf::SafePacketParserWrapper<Parser>::boolean_test()
- const
-{
- return i_;
-}
-
///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_
SENF_PARSER_FINALIZE(VoidPacketParser);
};
- /** \brief Iterator re-validating Parser wrapper
-
- An ordinary parser will be invalidated whenever the raw data container's size is
- changed. This can complicate some algorithms considerably.
-
- This wrapper will update the parsers iterator (the value returned by the i() member) on
- every access. This ensures that the iterator will stay valid.
-
- \attention Beware however, if you insert or remove data before the safe wrapper, the
- location will \e not be updated accordingly and therefore the parser will be
- invalid.
-
- Additionally a SafePacketParserWrapper has an uninitialized state. The only allowed operations in
- this state are the boolean test for validity and assigning another parser.
-
- \ingroup packetparser
- */
- template <class Parser>
- class SafePacketParserWrapper
- : public safe_bool< SafePacketParserWrapper<Parser> >
- {
- public:
- ///////////////////////////////////////////////////////////////////////////
- // Types
-
- ///////////////////////////////////////////////////////////////////////////
- ///\name Structors and default members
- ///@{
-
- // default copy constructor
- // default copy assignment
- // default destructor
- SafePacketParserWrapper(); ///< Create an empty uninitialized SafePacketParserWrapper
-
- // conversion constructors
- SafePacketParserWrapper(Parser parser); ///< Initialize SafePacketParserWrapper from \a parser
-
- SafePacketParserWrapper & operator=(Parser parser); ///< Assign \a parser to \c this
-
- ///@}
- ///////////////////////////////////////////////////////////////////////////
-
- Parser operator*() const; ///< Access the stored parser
- /**< On every access, the stored parsers iterator will be
- updated / re-validated. */
- Parser const * operator->() const; ///< Access the stored parser
- /**< On every access, the stored parsers iterator will be
- updated / re-validated. */
- bool boolean_test() const; ///< Check validity
-
- protected:
-
- private:
- mutable boost::optional<Parser> parser_;
- senf::safe_data_iterator i_;
- };
-
}
///////////////////////////////hh.e////////////////////////////////////////
BOOST_CHECK_EQUAL( senf::init_bytes<BarParser>::value, 6u );
}
-BOOST_AUTO_UNIT_TEST(safePacketParser)
-{
- senf::PacketInterpreter<VoidPacket>::ptr pi (senf::PacketInterpreter<VoidPacket>::create(6u));
- senf::SafePacketParserWrapper<senf::UInt16Parser> p;
-
- BOOST_CHECK( !p );
-
- p = senf::UInt16Parser(pi->data().begin(),&pi->data());
-
- BOOST_CHECK( p );
- (*p) = 0x1234u;
-
- BOOST_CHECK_EQUAL( (*p), 0x1234u );
- BOOST_CHECK_EQUAL( p->data()[0], 0x12u );
-
- p->data().resize(1024u);
- BOOST_CHECK_EQUAL( (*p), 0x1234u );
- (*p) = 0x2345u;
- BOOST_CHECK_EQUAL( p->data()[0], 0x23u );
-}
-
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
###########################################################################
-SENFSCons.AllIncludesHH(env, [ f for f in glob.glob("*.hh")
- if 'defined(HH_Packets__decls_)' in file(f).read() ])
+#SENFSCons.AllIncludesHH(env, [ f for f in glob.glob("*.hh")
+# if 'defined(HH_Packets__decls_)' in file(f).read() ])
SENFSCons.StandardTargets(env)
SENFSCons.Lib(env,
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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 2 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief SafeIterator inline non-template implementation */
+
+//#include "SafeIterator.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::safe_data_iterator
+
+prefix_ senf::safe_data_iterator::safe_data_iterator()
+ : data_(0), i_(0)
+{}
+
+prefix_ senf::safe_data_iterator::safe_data_iterator(PacketData & data)
+ : data_(&data), i_(0)
+{}
+
+prefix_ senf::safe_data_iterator::safe_data_iterator(PacketData & data, PacketData::iterator i)
+ : data_(&data), i_(std::distance(data.begin(),i))
+{}
+
+prefix_ senf::safe_data_iterator::safe_data_iterator(PacketParserBase const & parser)
+ : data_(&parser.data()), i_(std::distance(data_->begin(),parser.i()))
+{}
+
+prefix_ senf::PacketData::iterator senf::safe_data_iterator::i()
+ const
+{
+ SENF_ASSERT(data_);
+ return boost::next(data_->begin(),i_);
+}
+
+prefix_ senf::safe_data_iterator & senf::safe_data_iterator::operator=(PacketData::iterator i)
+{
+ SENF_ASSERT(data_);
+ i_ = std::distance(data_->begin(),i);
+ return *this;
+}
+
+prefix_ senf::safe_data_iterator &
+senf::safe_data_iterator::operator=(PacketParserBase const & parser)
+{
+ data_ = &parser.data();
+ i_ = std::distance(data_->begin(),parser.i());
+ return *this;
+}
+
+prefix_ senf::safe_data_iterator::operator senf::PacketData::iterator()
+ const
+{
+ return i();
+}
+
+prefix_ bool senf::safe_data_iterator::boolean_test()
+ const
+{
+ return data_;
+}
+
+prefix_ senf::PacketData & senf::safe_data_iterator::data()
+ const
+{
+ SENF_ASSERT(data_);
+ return *data_;
+}
+
+prefix_ senf::safe_data_iterator::value_type & senf::safe_data_iterator::dereference()
+ const
+{
+ return *i();
+}
+
+prefix_ bool senf::safe_data_iterator::equal(safe_data_iterator const & other)
+ const
+{
+ SENF_ASSERT(data_ == other.data_);
+ return i_ == other.i_;
+}
+
+prefix_ senf::safe_data_iterator::difference_type
+senf::safe_data_iterator::distance_to(safe_data_iterator const & other)
+ const
+{
+ SENF_ASSERT(data_ == other.data_);
+ return other.i_ - i_;
+}
+
+prefix_ void senf::safe_data_iterator::increment()
+{
+ ++i_;
+}
+
+prefix_ void senf::safe_data_iterator::decrement()
+{
+ SENF_ASSERT(i_>0);
+ --i_;
+}
+
+prefix_ void senf::safe_data_iterator::advance(difference_type n)
+{
+ SENF_ASSERT( -n < difference_type(i_) );
+ i_ += n;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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 2 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief SafeIterator inline template implementation */
+
+//#include "SafeIterator.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::SafePacketParserWrapper<Parser>
+
+template <class Parser>
+prefix_ senf::SafePacketParserWrapper<Parser>::SafePacketParserWrapper()
+ : parser_(), i_()
+{}
+
+template <class Parser>
+prefix_ senf::SafePacketParserWrapper<Parser>::SafePacketParserWrapper(Parser parser)
+ : parser_(parser), i_(parser)
+{}
+
+template <class Parser>
+prefix_ senf::SafePacketParserWrapper<Parser> & senf::SafePacketParserWrapper<Parser>::operator=(Parser parser)
+{
+ parser_ = parser;
+ i_ = parser;
+ return *this;
+}
+
+template <class Parser>
+prefix_ Parser senf::SafePacketParserWrapper<Parser>::operator*()
+ const
+{
+ SENF_ASSERT( i_ );
+ parser_->i_ = PacketParserBase::data_iterator(i_);
+ return *parser_;
+}
+
+template <class Parser>
+prefix_ Parser const * senf::SafePacketParserWrapper<Parser>::operator->()
+ const
+{
+ SENF_ASSERT( i_ );
+ parser_->i_ = PacketParserBase::data_iterator(i_);
+ return & (*parser_);
+}
+
+template <class Parser>
+prefix_ bool senf::SafePacketParserWrapper<Parser>::boolean_test()
+ const
+{
+ return i_;
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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 2 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief SafeIterator public header */
+
+#ifndef HH_SafeIterator_
+#define HH_SafeIterator_ 1
+
+#ifndef HH_Packets_
+#error "Don't include 'SafeIterator.hh' directly, include 'Packets.hh'"
+#endif
+
+// Custom includes
+#include <boost/iterator/iterator_facade.hpp>
+
+//#include "SafeIterator.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+ /** \brief Re-validating data iterator
+
+ This class is a wrapper around a PacketData::iterator instance. It will revalidate the
+ iterator on every access. This keeps the iterator valid even when the data container is
+ resized and thereby possibly relocated. The iterator will always point to the byte at the
+ same offset from the packets beginning. If data is inserted before this iterators position,
+ the data pointed to will of course change.
+
+ For this to work, the safe_data_iterator must be initialized with the container to which the
+ iterator belongs. After this initialization it can be used like any other iterator.
+ */
+ class safe_data_iterator
+ : public boost::iterator_facade< safe_data_iterator,
+ PacketData::value_type,
+ boost::random_access_traversal_tag >,
+ public comparable_safe_bool<safe_data_iterator>
+ {
+ public:
+ typedef PacketData::size_type size_type;
+
+ safe_data_iterator(); ///< Make uninitialized iterator
+ explicit safe_data_iterator(PacketData & data);
+ ///< Construct iterator only setting the data container
+ safe_data_iterator(PacketData & data, PacketData::iterator i);
+ ///< Initialize iterator to given position
+ explicit safe_data_iterator(PacketParserBase const & parser);
+ ///< Initialize iterator from parser
+ /**< The iterator will point to the parsers start
+ position. */
+
+ safe_data_iterator & operator=(PacketData::iterator i); ///< Assign iterator
+ /**< The iteator \a i must be from the container wo which \c
+ this iterator has been initialized. */
+ safe_data_iterator & operator=(PacketParserBase const & parser);
+ ///< Assign iterator from parser
+ /**< The iterator will point to the parser start
+ position. */
+
+ operator PacketData::iterator() const; ///< Convert to iterator
+
+ bool boolean_test() const; ///< Check, if iterator is initialized
+
+ PacketData & data() const; ///< Access data container
+
+ private:
+ friend class boost::iterator_core_access;
+
+ // iterator_facade interface
+
+ value_type & dereference() const;
+ bool equal(safe_data_iterator const & other) const;
+ difference_type distance_to(safe_data_iterator const & other) const;
+ void increment();
+ void decrement();
+ void advance(difference_type n);
+
+ PacketData::iterator i() const;
+
+ PacketData * data_;
+ size_type i_;
+ };
+
+ /** \brief Iterator re-validating Parser wrapper
+
+ An ordinary parser will be invalidated whenever the raw data container's size is
+ changed. This can complicate some algorithms considerably.
+
+ This wrapper will update the parsers iterator (the value returned by the i() member) on
+ every access. This ensures that the iterator will stay valid.
+
+ \attention Beware however, if you insert or remove data before the safe wrapper, the
+ location will \e not be updated accordingly and therefore the parser will be
+ invalid.
+
+ Additionally a SafePacketParserWrapper has an uninitialized state. The only allowed operations in
+ this state are the boolean test for validity and assigning another parser.
+
+ \ingroup packetparser
+ */
+ template <class Parser>
+ class SafePacketParserWrapper
+ : public safe_bool< SafePacketParserWrapper<Parser> >
+ {
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///@{
+
+ // default copy constructor
+ // default copy assignment
+ // default destructor
+ SafePacketParserWrapper(); ///< Create an empty uninitialized SafePacketParserWrapper
+
+ // conversion constructors
+ SafePacketParserWrapper(Parser parser); ///< Initialize SafePacketParserWrapper from \a parser
+
+ SafePacketParserWrapper & operator=(Parser parser); ///< Assign \a parser to \c this
+
+ ///@}
+ ///////////////////////////////////////////////////////////////////////////
+
+ Parser operator*() const; ///< Access the stored parser
+ /**< On every access, the stored parsers iterator will be
+ updated / re-validated. */
+ Parser const * operator->() const; ///< Access the stored parser
+ /**< On every access, the stored parsers iterator will be
+ updated / re-validated. */
+ bool boolean_test() const; ///< Check validity
+
+ protected:
+
+ private:
+ mutable boost::optional<Parser> parser_;
+ senf::safe_data_iterator i_;
+ };
+
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(HH_Packets__decls_) && !defined(HH_SafeIterator_i_)
+#define HH_SafeIterator_i_
+#include "SafeIterator.cci"
+//#include "SafeIterator.ct"
+#include "SafeIterator.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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 2 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief SafeIterator.test unit tests */
+
+//#include "SafeIterator.test.hh"
+//#include "SafeIterator.test.ih"
+
+// Custom includes
+#include "Packets.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+ struct VoidPacket : public senf::PacketTypeBase {};
+}
+
+BOOST_AUTO_UNIT_TEST(safePacketParser)
+{
+ senf::PacketInterpreter<VoidPacket>::ptr pi (senf::PacketInterpreter<VoidPacket>::create(6u));
+ senf::SafePacketParserWrapper<senf::UInt16Parser> p;
+
+ BOOST_CHECK( !p );
+
+ p = senf::UInt16Parser(pi->data().begin(),&pi->data());
+
+ BOOST_CHECK( p );
+ (*p) = 0x1234u;
+
+ BOOST_CHECK_EQUAL( (*p), 0x1234u );
+ BOOST_CHECK_EQUAL( p->data()[0], 0x12u );
+
+ p->data().resize(1024u);
+ BOOST_CHECK_EQUAL( (*p), 0x1234u );
+ (*p) = 0x2345u;
+ BOOST_CHECK_EQUAL( p->data()[0], 0x23u );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
def configFilesOpts(target, source, env, for_signature):
return [ '-I%s' % os.path.split(f)[1] for f in env['LOCAL_CONFIG_FILES'] ]
+# Options used to debug inlining:
+#
+# INLINE_OPTS = [ '-finline-limit=20000', '--param','large-function-growth=10000',
+# '--param', 'large-function-insns=10000', '--param','inline-unit-growth=10000',
+# '-fvisibility-inlines-hidden', '-fno-inline-functions', '-Winline' ]
+#
+# BEWARE: You need lots of ram to compile with these settings (approx 1G)
+#
+
+INLINE_OPTS = [ '-finline-limit=5000' ]
+
env.Append(
CPPPATH = [ '#/include' ],
+ CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ] + INLINE_OPTS,
LIBS = [ 'readline', 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB' ],
TEST_EXTRA_LIBS = [ '$BOOSTFSLIB' ],
DOXY_XREF_TYPES = [ 'bug', 'fixme', 'todo', 'idea' ],
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
-prefix_ senf::SchedulerBinding::~SchedulerBinding()
-{
- disable();
-}
-
prefix_ void senf::SchedulerBinding::enable()
{
if (! enabled_) {
return enabled_;
}
+prefix_ senf::SchedulerBinding::~SchedulerBinding()
+{
+ disable();
+}
+
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
///////////////////////////////////////////////////////////////////////////
// senf::ClockService
+////////////////////////////////////////
+// private members
+
+prefix_ bool senf::ClockService::checkSkew(boost::posix_time::ptime time)
+{
+ boost::posix_time::ptime h (heartbeat_); // reduce chance for race condition
+ return time < h || (time - h) > boost::posix_time::seconds(2*CheckInterval);
+}
+
+prefix_ void senf::ClockService::clockSkew(boost::posix_time::ptime time,
+ boost::posix_time::ptime expected)
+{
+ base_ += (time - expected);
+}
+
+prefix_ senf::ClockService::clock_type senf::ClockService::clock_m(abstime_type time)
+{
+ ///\fixme What happens, if base_ is changed in SIGALRM while reading it here ?
+
+ // Idea: Have *two* base values: one is written by the SIGALRM handler, the other is only
+ // Written by synchronous code. If they differ, we block signals, copy over and continue. If
+ // they transiently differ because we are reading the SIGALRM value while it is being changed
+ // this does not matter: We will then still copy it over.
+
+ boost::posix_time::time_duration delta (time - base_);
+ return clock_type( delta.ticks() )
+ * clock_type( 1000000000UL / boost::posix_time::time_duration::ticks_per_second() );
+}
+
+prefix_ senf::ClockService::clock_type senf::ClockService::now_m()
+{
+ // We want to make the normal case (no skew) really fast. This first 'checkSkew' *might*
+ // transiently fail if a SIGALRM is delivered in the midst of the test. updateSkew will
+ // therefore block signals and do the check again to make sure.
+ //
+ // The opposite case (the test returns 'false' even though it should return 'true') is so highly
+ // improbable that it is treated as academic. (it will be catched by the next SIGALRM)
+
+ boost::posix_time::ptime time (boost::posix_time::microsec_clock::universal_time());
+ if (checkSkew(time))
+ updateSkew(time);
+
+ // 'clock' will pick up the corrected base_ value if needed.
+ return clock_m(time);
+}
+
+prefix_ senf::ClockService::abstime_type senf::ClockService::abstime_m(clock_type clock)
+{
+#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
+ return base_ + boost::posix_time::nanoseconds(clock);
+#else
+ return base_ + boost::posix_time::microseconds((clock+500)/1000);
+#endif
+}
+
+// public members
+
prefix_ senf::ClockService::clock_type senf::ClockService::now()
{
return instance().now_m();
return clock( boost::posix_time::from_time_t(time) );
}
-prefix_ senf::ClockService::clock_type senf::ClockService::from_timeval(timeval const & time)
-{
- return from_time_t(time.tv_sec) + ClockService::microseconds(time.tv_usec);
-}
-
prefix_ senf::ClockService::clock_type senf::ClockService::nanoseconds(int64_type v)
{
return v;
return v / hours(24);
}
-prefix_ void senf::ClockService::restart()
-{
- instance().restart_m();
-}
-
-////////////////////////////////////////
-// private members
-
-prefix_ senf::ClockService::clock_type senf::ClockService::now_m()
-{
- // We want to make the normal case (no skew) really fast. This first 'checkSkew' *might*
- // transiently fail if a SIGALRM is delivered in the midst of the test. updateSkew will
- // therefore block signals and do the check again to make sure.
- //
- // The opposite case (the test returns 'false' even though it should return 'true') is so highly
- // improbable that it is treated as academic. (it will be catched by the next SIGALRM)
-
- boost::posix_time::ptime time (boost::posix_time::microsec_clock::universal_time());
- if (checkSkew(time))
- updateSkew(time);
-
- // 'clock' will pick up the corrected base_ value if needed.
- return clock_m(time);
-}
-
-prefix_ senf::ClockService::abstime_type senf::ClockService::abstime_m(clock_type clock)
-{
-#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
- return base_ + boost::posix_time::nanoseconds(clock);
-#else
- return base_ + boost::posix_time::microseconds((clock+500)/1000);
-#endif
-}
-
-prefix_ senf::ClockService::clock_type senf::ClockService::clock_m(abstime_type time)
-{
- ///\fixme What happens, if base_ is changed in SIGALRM while reading it here ?
-
- // Idea: Have *two* base values: one is written by the SIGALRM handler, the other is only
- // Written by synchronous code. If they differ, we block signals, copy over and continue. If
- // they transiently differ because we are reading the SIGALRM value while it is being changed
- // this does not matter: We will then still copy it over.
-
- boost::posix_time::time_duration delta (time - base_);
- return clock_type( delta.ticks() )
- * clock_type( 1000000000UL / boost::posix_time::time_duration::ticks_per_second() );
-}
-
-prefix_ bool senf::ClockService::checkSkew(boost::posix_time::ptime time)
+prefix_ senf::ClockService::clock_type senf::ClockService::from_timeval(timeval const & time)
{
- boost::posix_time::ptime h (heartbeat_); // reduce chance for race condition
- return time < h || (time - h) > boost::posix_time::seconds(2*CheckInterval);
+ return from_time_t(time.tv_sec) + ClockService::microseconds(time.tv_usec);
}
-prefix_ void senf::ClockService::clockSkew(boost::posix_time::ptime time,
- boost::posix_time::ptime expected)
+prefix_ void senf::ClockService::restart()
{
- base_ += (time - expected);
+ instance().restart_m();
}
///////////////////////////////cci.e///////////////////////////////////////
// Custom includes
#include <algorithm>
+#include <boost/utility/value_init.hpp>
#include "../Utils/Buffer.hh"
#define prefix_
senf::ClientSocketHandle<SPolicy>::readfrom(unsigned limit)
{
std::string rv;
- typename SPolicy::AddressingPolicy::Address addr;
- this->readfrom(rv,addr,limit);
- return std::make_pair(rv,addr);
+ boost::value_initialized<typename SPolicy::AddressingPolicy::Address> addr;
+ this->readfrom(rv,addr.data(),limit);
+ return std::make_pair(rv,addr.data());
}
template <class SPolicy>
return rv>0;
}
+prefix_ senf::FileBody::~FileBody()
+{}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
///////////////////////////////////////////////////////////////////////////
// senf::FileHandle
+prefix_ senf::FileBody & senf::FileHandle::body()
+{
+ SENF_ASSERT(body_);
+ return *body_;
+}
+
+prefix_ senf::FileBody const & senf::FileHandle::body()
+ const
+{
+ SENF_ASSERT(body_);
+ return *body_;
+}
+
prefix_ void senf::FileHandle::close()
{
body().close();
: body_(body)
{}
-prefix_ senf::FileBody & senf::FileHandle::body()
-{
- SENF_ASSERT(body_);
- return *body_;
-}
-
-prefix_ senf::FileBody const & senf::FileHandle::body()
- const
-{
- SENF_ASSERT(body_);
- return *body_;
-}
-
prefix_ senf::FileBody & senf::FileHandle::body(FileHandle & handle)
{
return handle.body();
constructor not some arbitrary id even if you overload
all the virtual members. If the file descriptor is -1 the
resulting body/handle is not valid() */
+ virtual ~FileBody();
- // NO DESTRUCTOR HERE - destructors and virtual functions don't mix. What would be in the
- // the destructor is in 'destroyClose()' which is called from FileHandle::~FileHandle()
- // *before* the last handle dies.
+ // NO DESTRUCTOR HERE (that is, only an empty virtual destructor) - destructors and virtual
+ // functions don't mix. What would be in the the destructor is in 'destroyClose()' which is
+ // called from FileHandle::~FileHandle() *before* the last handle dies.
// no copy
// no conversion constructors
return INet4Address(v,IsInAddr);
}
+prefix_ senf::INet4Address::inaddr_type & senf::INet4Address::iref()
+{
+ return *reinterpret_cast<inaddr_type *>(&(*this)[0]);
+}
+
+prefix_ senf::INet4Address::inaddr_type senf::INet4Address::iref()
+ const
+{
+ return *reinterpret_cast<inaddr_type const *>(&(*this)[0]);
+}
+
+prefix_ senf::INet4Address::inaddr_type senf::INet4Address::inaddr()
+ const
+{
+ return iref();
+}
+
prefix_ senf::INet4Address::INet4Address(inaddr_type addr, InAddr_t)
{
iref() = addr;
return inaddr();
}
-prefix_ senf::INet4Address::inaddr_type senf::INet4Address::inaddr()
+///////////////////////////////////////////////////////////////////////////
+// senf::INet4Network
+
+prefix_ unsigned senf::INet4Network::prefix_len()
const
{
- return iref();
+ return prefix_len_;
}
-prefix_ senf::INet4Address::inaddr_type & senf::INet4Address::iref()
-{
- return *reinterpret_cast<inaddr_type *>(&(*this)[0]);
-}
+////////////////////////////////////////
+// private members
-prefix_ senf::INet4Address::inaddr_type senf::INet4Address::iref()
+prefix_ boost::uint32_t senf::INet4Network::mask()
const
{
- return *reinterpret_cast<inaddr_type const *>(&(*this)[0]);
+ // This is correct as long as the system is using 2-complement arithmetic ...
+ return (~((boost::uint32_t(1u)<<(32u-prefix_len()))-1u)) & 0xFFFFFFFFu;
}
-///////////////////////////////////////////////////////////////////////////
-// senf::INet4Network
+////////////////////////////////////////
+// public members
prefix_ senf::INet4Network::INet4Network()
: prefix_len_(), address_()
return address_;
}
-prefix_ unsigned senf::INet4Network::prefix_len()
- const
-{
- return prefix_len_;
-}
-
prefix_ bool senf::INet4Network::boolean_test()
const
{
return INet4Network(host(net << (32-prefix_len)),prefix_len);
}
-////////////////////////////////////////
-// private members
-
-prefix_ boost::uint32_t senf::INet4Network::mask()
- const
-{
- // This is correct as long as the system is using 2-complement arithmetic ...
- return (~((boost::uint32_t(1u)<<(32u-prefix_len()))-1u)) & 0xFFFFFFFFu;
-}
-
///////////////////////////////////////////////////////////////////////////
// namespace members
((boost::uint64_t((*this)[7]) & 0xff) );
}
-prefix_ bool senf::INet6Address::hasEuid64()
- const
-{
- return unicast() && ((*this)[0]&0xE0u) != 0u;
-}
-
prefix_ boost::uint64_t senf::INet6Address::id()
const
{
return (*this)[8] & 1u;
}
-prefix_ bool senf::INet6Address::unicast()
+prefix_ senf::INet4Address senf::INet6Address::inet4address()
const
{
- return ! multicast();
+ return INet4Address::from_data(&(*this)[12]);
+}
+
+prefix_ bool senf::INet6Address::inet4Mapped()
+ const
+{
+ return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this);
}
prefix_ bool senf::INet6Address::multicast()
: GlobalScope;
}
-prefix_ bool senf::INet6Address::globalScope()
+prefix_ bool senf::INet6Address::unicast()
const
{
- return scope() == GlobalScope;
+ return ! multicast();
}
-
-prefix_ bool senf::INet6Address::linkScope()
+
+prefix_ bool senf::INet6Address::hasEuid64()
const
{
- return scope() == LinkScope;
+ return unicast() && ((*this)[0]&0xE0u) != 0u;
}
-prefix_ senf::INet4Address senf::INet6Address::inet4address()
+prefix_ bool senf::INet6Address::globalScope()
const
{
- return INet4Address::from_data(&(*this)[12]);
+ return scope() == GlobalScope;
}
-
-prefix_ bool senf::INet6Address::inet4Compatible()
+
+prefix_ bool senf::INet6Address::linkScope()
const
{
- return CheckINet6Network<0u,96>::match(*this);
+ return scope() == LinkScope;
}
-prefix_ bool senf::INet6Address::inet4Mapped()
+prefix_ bool senf::INet6Address::inet4Compatible()
const
{
- return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this);
+ return CheckINet6Network<0u,96>::match(*this);
}
prefix_ bool senf::INet6Address::globalMulticastAddr()
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
+prefix_ void senf::LLSocketAddress::clear()
+{
+ ::memset(&addr_,0,sizeof(addr_));
+ addr_.sll_family = AF_PACKET;
+}
+
+prefix_ void senf::LLSocketAddress::address(MACAddress const & addr)
+{
+ std::copy(addr.begin(), addr.end(),&addr_.sll_addr[0]);
+}
+
prefix_ senf::LLSocketAddress::LLSocketAddress()
{
clear();
}
+prefix_ void senf::LLSocketAddress::protocol(unsigned prot)
+{
+ addr_.sll_protocol = htons(prot);
+}
+
prefix_ senf::LLSocketAddress::LLSocketAddress(unsigned prot, std::string const & iface)
{
clear();
interface(iface);
}
-prefix_ void senf::LLSocketAddress::clear()
-{
- ::memset(&addr_,0,sizeof(addr_));
- addr_.sll_family = AF_PACKET;
-}
-
prefix_ unsigned senf::LLSocketAddress::protocol()
const
{
return MACAddress::from_data(&addr_.sll_addr[0]);
}
-prefix_ void senf::LLSocketAddress::address(MACAddress const & addr)
-{
- std::copy(addr.begin(), addr.end(),&addr_.sll_addr[0]);
-}
-
-prefix_ void senf::LLSocketAddress::protocol(unsigned prot)
-{
- addr_.sll_protocol = htons(prot);
-}
-
prefix_ struct sockaddr * senf::LLSocketAddress::sockaddr_p()
{
return reinterpret_cast<struct sockaddr *>(&addr_);
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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 2 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief SocketPolicy non-inline non-template implementation */
+
+#include "SocketPolicy.hh"
+#include "SocketPolicy.ih"
+
+// Custom includes
+
+//#include "SocketPolicy.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ senf::AddressingPolicyBase::~AddressingPolicyBase()
+{}
+
+prefix_ senf::FramingPolicyBase::~FramingPolicyBase()
+{}
+
+prefix_ senf::CommunicationPolicyBase::~CommunicationPolicyBase()
+{}
+
+prefix_ senf::ReadPolicyBase::~ReadPolicyBase()
+{}
+
+prefix_ senf::WritePolicyBase::~WritePolicyBase()
+{}
+
+prefix_ senf::SocketPolicyBase::~SocketPolicyBase()
+{}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "SocketPolicy.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
*/
struct AddressingPolicyBase
{
- virtual ~AddressingPolicyBase() {}
+ virtual ~AddressingPolicyBase();
class Address { Address(); };
};
*/
struct FramingPolicyBase
{
- virtual ~FramingPolicyBase() {}
+ virtual ~FramingPolicyBase();
};
/** \brief Policy defining, how peers are selected
*/
struct CommunicationPolicyBase
{
- virtual ~CommunicationPolicyBase() {}
+ virtual ~CommunicationPolicyBase();
};
/** \brief Policy defining the readability
*/
struct ReadPolicyBase
{
- virtual ~ReadPolicyBase() {}
+ virtual ~ReadPolicyBase();
};
/** \brief Policy defining the writability
*/
struct WritePolicyBase
{
- virtual ~WritePolicyBase() {}
+ virtual ~WritePolicyBase();
};
// The implementation file will for each Policy declared above
struct SocketPolicyBase
{
- virtual ~SocketPolicyBase() {}
+ virtual ~SocketPolicyBase();
# define SP_Declare(x1,x2,SomePolicy) \
virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () \
///////////////////////////////////////////////////////////////////////////
// senf::log::detail::AreaBase
+prefix_ senf::log::detail::AreaBase::~AreaBase()
+{}
+
prefix_ void senf::log::detail::AreaBase::updateRoutingCache(Target & target,
StreamBase const & stream,
unsigned limit)
/** \brief Internal: Area base class */
struct AreaBase
{
- virtual ~AreaBase() {};
+ virtual ~AreaBase();
std::string fullName() const;
virtual std::string v_name() const;
unsigned senf::log::detail::StreamBase::nStreams = 0;
+///////////////////////////////////////////////////////////////////////////
+// senf::log::detail::StreamBase
+
+prefix_ senf::log::detail::StreamBase::~StreamBase()
+{}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "Stream.mpp"
struct StreamBase
{
StreamBase();
- virtual ~StreamBase() {};
+ virtual ~StreamBase();
std::string fullName() const;
virtual std::string v_name() const;
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::log::TimeSource
-
-prefix_ senf::log::time_type senf::log::TimeSource::now()
-{
- return detail::TimeSourceManager::instance().now();
-}
-
-///////////////////////////////////////////////////////////////////////////
// senf::log::detail::TimeSourceManager
prefix_ senf::log::detail::TimeSourceManager::TimeSourceManager()
}
///////////////////////////////////////////////////////////////////////////
+// senf::log::TimeSource
+
+prefix_ senf::log::time_type senf::log::TimeSource::now()
+{
+ return detail::TimeSourceManager::instance().now();
+}
+
+///////////////////////////////////////////////////////////////////////////
// namespace senf::log members
prefix_ void senf::log::timeSource(std::auto_ptr<TimeSource> source)
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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 2 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief TypeIdValue non-inline non-template implementation */
+
+#include "TypeIdValue.hh"
+//#include "TypeIdValue.ih"
+
+// Custom includes
+
+//#include "TypeIdValue.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ senf::TypeIdValue::Value::~Value()
+{}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "TypeIdValue.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
template <class Type> TypeIdValue(Type *);
struct Value {
- virtual ~Value() {}
+ virtual ~Value();
virtual std::type_info const & id() = 0;
virtual Value * clone() = 0;
};
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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 2 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief intrusive_refcount non-inline non-template implementation */
+
+#include "intrusive_refcount.hh"
+//#include "intrusive_refcount.ih"
+
+// Custom includes
+
+//#include "intrusive_refcount.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ senf::intrusive_refcount_base::~intrusive_refcount_base()
+{}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "intrusive_refcount.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
: refcount_(0)
{}
-prefix_ senf::intrusive_refcount_base::~intrusive_refcount_base()
-{}
-
prefix_ void senf::intrusive_refcount_base::add_ref()
{
++refcount_;
# These are the default compilation parameters. We should probably
# make these configurable
- env.Append(CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ],
- LOCALLIBDIR = [ '#' ],
+ env.Append(LOCALLIBDIR = [ '#' ],
LIBPATH = [ '$LOCALLIBDIR' ])
if env['final']:
else:
# The boost-regex library is not compiled with _GLIBCXX_DEBUG so this fails:
# CPPDEFINES = [ '_GLIBCXX_DEBUG' ],
- env.Append(CXXFLAGS = [ '-O0', '-g', '-fno-inline' ],
+ env.Append(CXXFLAGS = [ '-O0', '-g' ],
CPPDEFINES = [ 'SENF_DEBUG' ],
LINKFLAGS = [ '-g', '-rdynamic' ])