be removed as soon as possible). The example application now
contains a helper routine to produce a packet hexdump. We will
skip this routine here and go directly to the \c main function
-
+
\skip main
\until try
\skip while
\until read
-
+
The next step is, to parse the data read from the socket as an
Ethernet packet
\until ;
-
+
Lets digest this line step by step: We declare a variable named \c
packet as a smart pointer to an \c EthernetPacket instance. \c ptr
is a typedef member of all Packet classes for the corresponding
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// mode: flyspell
// mode: auto-fill
-// ispell-local-dictionary: "american"
// End:
-
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
- Preamble
+ Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
The precise terms and conditions for copying, distribution and
modification follow.
\f
- GNU GENERAL PUBLIC LICENSE
+ GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
- NO WARRANTY
+ NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
- END OF TERMS AND CONDITIONS
+ END OF TERMS AND CONDITIONS
\f
- How to Apply These Terms to Your New Programs
+ How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
\li modular framework design
\li utilizing the power of modern C++
\li very low overhead for frequently called members
- \li extensible design
+ \li extensible design
\li concise interface
\section start Getting started
*/
/** \page build Building the framework
-
+
This procedure will test building the complete framework
including the unit tests and the Sniffer test application. This
build is \e not needed to use the framework since every project
continue to setup your own project using SENF.
\see \ref components \n
- \ref svnsetup
+ \ref svnsetup
\section checkout Getting the code
\see \ref build \n
\ref svnsetup
-
+
\section libSocket libSocket: C++ abstraction of the BSD socket API
This library provides a high performance and object oriented
miscellaneous tools and utilities. We have
\li Simple functions to manage daemon processes
- \li Standard exception classes
+ \li Standard exception classes
\li senf::intrusive_refcount to simplify the implementation
- of classes usable with boost::intrusive_ptr
+ of classes usable with boost::intrusive_ptr
\li boost::bind extensions
- \li An interface to the \c g++ demangler integrated with type_info
+ \li An interface to the \c g++ demangler integrated with type_info
\li Typedefs and rudimentary methods to simplify handling
- high-resolution time values
+ high-resolution time values
\see <a href="../../Utils/doc/html/index.html">libUtils API
reference</a>
*/
/** \page svnsetup Setting up a new project using SENF
-
+
The preferred way to use SENF in a new project is to rely on
Subversion and make use of the SENFSCons build environment. The
following sections will describe, how this setup works.
\c svn:externals. This will instruct \c svn to auutomatically
check out the needed directories from the BerliOS SENF
repository. Change to the 'Foo' directory and type
-
+
<pre>
$ svn propedit svn:externals .
</pre>
</pre>
and the code will be checked out into the corresponding
- directories.
+ directories.
\section new_conf Configuring SENFSCons
you can also build only a subdirectory by changing to it and
running
-
+
<pre>
$ scons -u [target]
</pre>
*/
/** \page overview Introduction to the framework
-
+
The SENF framework is relatively complex and makes use of advanced
features of the C++ language. To make the most efficient use of
the framework, you should have at least a basic understanding of
example application is provided in the SENF repository in the \c
Sniffer module. Peruse this example to get a first look at how to
make use of SENF.
-
+
When building a network Application with SENF, you will use
several modules:
-
+
\li Use the <a href="../../Socket/doc/html/index.html">Socket
- library</a> for network communication needs. This library
- includes support for raw and packet sockets to allow low level
- network access.
+ library</a> for network communication needs. This library
+ includes support for raw and packet sockets to allow low level
+ network access.
\li Use the <a
- href="../../Scheduler/doc/html/index.html">Scheduler
- library</a> to coordinate the asynchronous event
- processing. This drastically reduces the number of threads
- needed in your application and will greatly enhance the overall
- responsiveness.
+ href="../../Scheduler/doc/html/index.html">Scheduler
+ library</a> to coordinate the asynchronous event
+ processing. This drastically reduces the number of threads
+ needed in your application and will greatly enhance the overall
+ responsiveness.
\li To interpret low level network packets, use the <a
- href="../../Packets/doc/html/index.html">Packets
- library</a>. This library will provide efficient and
- convenient access to all protocol fields. It supports parsing as
- well as modifying and creating packets. It has default support
- for the most important internet protocols and is highly
- extensible with new protocols.
+ href="../../Packets/doc/html/index.html">Packets
+ library</a>. This library will provide efficient and
+ convenient access to all protocol fields. It supports parsing as
+ well as modifying and creating packets. It has default support
+ for the most important internet protocols and is highly
+ extensible with new protocols.
\li Go over the <a href="../../Utils/doc/html/index.html">Utils
- library</a>. It contains small helpers to
- simplify tasks like daemonization, exception handling,
+ library</a>. It contains small helpers to
+ simplify tasks like daemonization, exception handling,
debugging and so on.
The simplest way to get started is: copy the Sniffer application
and start to modify it.
\see \ref example \n
- \ref components \n
+ \ref components \n
\ref svnsetup \n
\ref build
*/
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// mode: flyspell
// mode: auto-fill
-// ispell-local-dictionary: "american"
// End:
-
+++ /dev/null
-SConfig
-.doc.stamp
-.test.stamp
-.sconf_temp
-.sconsign
-config.log
-doc
-test
-structure.png
-.clean
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class Arg>
prefix_ senf::DataPacket::DataPacket(Arg const & arg)
- : Packet(arg)
+ : Packet(arg)
{}
///////////////////////////////cti.e///////////////////////////////////////
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
private:
template <class Arg>
DataPacket(Arg const & arg);
-
+
virtual void v_nextInterpreter() const;
virtual void v_finalize();
virtual void v_dump(std::ostream & os) const;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::EthVLanPacket>
+ senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::EthVLanPacket>
registerEthVLanPacket(0x8100);
}
const
{
/** \todo Add LLC/SNAP support -> only use the registry
- for type() values >=1536, otherwise expect an LLC header */
+ for type() values >=1536, otherwise expect an LLC header */
registerInterpreter(type(),begin()+bytes(),end());
}
namespace {
-
+
void dumpmac(std::ostream & os, senf::EthernetPacket::Parse_MAC mac)
{
for (unsigned i = 0; i < 6; ++i) {
- if (i > 0)
+ if (i > 0)
os << ':';
os << std::hex << std::setw(2) << std::setfill('0')
<< unsigned(mac[i]);
os << "Ethernet 802.3";
else if (type() >= 0x600)
os << "Ethernet II (DIX)";
- else
+ else
os << "Ethernet 802.3 (bad ethertype >1500 and <1536)";
os << ": \n"
<< " destination : ";
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace senf {
-
+
template <class Iterator=nil, class IPacket=nil>
struct Parse_Ethernet : public ParserBase<Iterator,IPacket>
{
Parse_Ethernet(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
static unsigned bytes() { return 14; }
-
+
///////////////////////////////////////////////////////////////////////////
typedef Parse_Array < 6, Parse_UInt8<>, Iterator > Parse_MAC;
typedef Parse_UInt16 < Iterator > Parse_Type;
-
+
Parse_MAC destination() const { return Parse_MAC (this->i() ); }
Parse_MAC source() const { return Parse_MAC (this->i() + Parse_MAC::size() ); }
Parse_Type type() const { return Parse_Type (this->i() + 2*Parse_MAC::size() ); }
};
struct EtherTypes {
- // See http://www.iana.org/assignments/ethernet-numbers
+ // See http://www.iana.org/assignments/ethernet-numbers
typedef boost::uint16_t key_t;
};
class EthernetPacket
- : public Packet,
- public Parse_Ethernet<Packet::iterator, EthernetPacket>,
+ : public Packet,
+ public Parse_Ethernet<Packet::iterator, EthernetPacket>,
public PacketRegistryMixin<EtherTypes,EthernetPacket>
{
using PacketRegistryMixin<EtherTypes,EthernetPacket>::registerInterpreter;
Parse_EthVLan(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
static unsigned bytes() { return 4; }
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UIntField < 0, 3, Iterator > Parse_Priority;
typedef Parse_Flag < 3, Iterator > Parse_CFI;
typedef Parse_UIntField < 4, 16, Iterator > Parse_VLanId;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
BOOST_CHECK_EQUAL( p->source()[0], 0x07 );
BOOST_CHECK_EQUAL( p->type(), 0x1011 );
- BOOST_CHECK_THROW( Packet::create<EthernetPacket>(data, data+sizeof(data)-1),
+ BOOST_CHECK_THROW( Packet::create<EthernetPacket>(data, data+sizeof(data)-1),
TruncatedPacketException );
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
iterator end_trailer() const;
static size_type trailer_len();
- static bool check(iterator const & b, iterator const & e)
+ static bool check(iterator const & b, iterator const & e)
{ return unsigned(e - b) >= HEADER + TRAILER; }
-
+
protected:
- private:
+ private:
template <class Arg>
GenericPacket(Arg const & arg);
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV4Packet>
+ senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV4Packet>
registerIpV4Packet (0x0800);
senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV4Packet>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace senf {
-
+
template <class Iterator=nil, class IpV4Packet=nil>
struct Parse_IpV4 : public ParserBase<Iterator,IpV4Packet>
{
Parse_IpV4(Iterator const & i) : ParserBase<Iterator,IpV4Packet>(i) {}
static unsigned bytes() { return 20; }
-
+
///////////////////////////////////////////////////////////////////////////
typedef Parse_UIntField < 0, 4, Iterator > Parse_Version;
typedef Parse_Flag < 1, Iterator > Parse_DF;
typedef Parse_Flag < 2, Iterator > Parse_MF;
typedef Parse_UIntField < 3, 16, Iterator > Parse_Frag;
- typedef Parse_UInt32 < Iterator > Parse_32bit;
-
+ typedef Parse_UInt32 < Iterator > Parse_32bit;
+
Parse_Version version() const { return Parse_Version (this->i() ); }
Parse_IHL ihl() const { return Parse_IHL (this->i() ); }
Parse_8bit tos() const { return Parse_8bit (this->i() + 1 ); }
Parse_MF mf() const { return Parse_MF (this->i() + 6 ); }
Parse_Frag frag() const { return Parse_Frag (this->i() + 6 ); }
Parse_8bit ttl() const { return Parse_8bit (this->i() + 8 ); }
- Parse_8bit protocol() const { return Parse_8bit (this->i() + 9 ); }
- Parse_16bit crc() const { return Parse_16bit (this->i() + 10 ); }
- Parse_32bit source() const { return Parse_32bit (this->i() + 12 ); }
+ Parse_8bit protocol() const { return Parse_8bit (this->i() + 9 ); }
+ Parse_16bit crc() const { return Parse_16bit (this->i() + 10 ); }
+ Parse_32bit source() const { return Parse_32bit (this->i() + 12 ); }
Parse_32bit destination() const { return Parse_32bit (this->i() + 16 ); }
};
struct IpTypes {
- // See http://www.iana.org/assignments/protocol-numbers
- // Also used by IPv6
+ // See http://www.iana.org/assignments/protocol-numbers
+ // Also used by IPv6
typedef boost::uint16_t key_t;
};
class IpV4Packet
- : public Packet,
- public Parse_IpV4<Packet::iterator,IpV4Packet>,
+ : public Packet,
+ public Parse_IpV4<Packet::iterator,IpV4Packet>,
public PacketRegistryMixin<IpTypes,IpV4Packet>
{
using PacketRegistryMixin<IpTypes,IpV4Packet>::registerInterpreter;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
BOOST_AUTO_UNIT_TEST(ipV4Packet_parser)
{
- unsigned char data[] = { 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0A, 0x0B, 0x0C,
- 0x11, 0x12, 0x13, 0x14,
- 0x15, 0x16, 0x17, 0x18
- };
+ unsigned char data[] = { 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x0C,
+ 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18
+ };
typedef unsigned char * iterator;
Parse_IpV4<iterator> p(data);
BOOST_CHECK_EQUAL( static_cast<unsigned>(p.crc()), 0x0B0Cu );
BOOST_CHECK_EQUAL( p.source(), 0x11121314u );
BOOST_CHECK_EQUAL( p.destination(), 0x15161718u );
-
+
}
-
+
BOOST_AUTO_UNIT_TEST(ipV4Packet_packet)
{
- unsigned char data[] = { 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0A, 0x0B, 0x0C,
- 0x11, 0x12, 0x13, 0x14,
- 0x15, 0x16, 0x17, 0x18
- };
+ unsigned char data[] = { 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x0C,
+ 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18
+ };
IpV4Packet::ptr p (Packet::create<IpV4Packet>(data, data+sizeof(data)));
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
// See RFC2460
template <class Iterator=nil, class IPacket=nil>
struct Parse_IpV6Extension_Fragment
- : public ParserBase<Iterator,IPacket>
+ : public ParserBase<Iterator,IPacket>
{
template <class I, class P=nil>
struct rebind { typedef Parse_IpV6Extension_Fragment<I,P> parser; };
Parse_IpV6Extension_Fragment(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
static unsigned bytes() { return 8; }
-
+
///////////////////////////////////////////////////////////////////////////
- typedef Parse_UInt8 < Iterator > Parse_8bit;
- typedef Parse_UIntField < 0, 13, Iterator > Parse_Offset;
- typedef Parse_UIntField < 13, 15, Iterator > Parse_Reserved;
- typedef Parse_Flag < 15, Iterator > Parse_More;
- typedef Parse_UInt32 < Iterator > Parse_32bit;
-
- Parse_8bit nextHeader() const { return Parse_8bit (this->i() ); }
- Parse_8bit reserved1() const { return Parse_8bit (this->i() + 1 ); }
- Parse_Offset fragmentOffset() const { return Parse_Offset (this->i() + 2 ); }
- Parse_Reserved reserved2() const { return Parse_Reserved (this->i() + 2 ); }
- Parse_More moreFragments() const { return Parse_More (this->i() + 2 ); }
- Parse_32bit id() const { return Parse_32bit (this->i() + 4 ); }
+ typedef Parse_UInt8 < Iterator > Parse_8bit;
+ typedef Parse_UIntField < 0, 13, Iterator > Parse_Offset;
+ typedef Parse_UIntField < 13, 15, Iterator > Parse_Reserved;
+ typedef Parse_Flag < 15, Iterator > Parse_More;
+ typedef Parse_UInt32 < Iterator > Parse_32bit;
+
+ Parse_8bit nextHeader() const { return Parse_8bit (this->i() ); }
+ Parse_8bit reserved1() const { return Parse_8bit (this->i() + 1 ); }
+ Parse_Offset fragmentOffset() const { return Parse_Offset (this->i() + 2 ); }
+ Parse_Reserved reserved2() const { return Parse_Reserved (this->i() + 2 ); }
+ Parse_More moreFragments() const { return Parse_More (this->i() + 2 ); }
+ Parse_32bit id() const { return Parse_32bit (this->i() + 4 ); }
};
class IpV6Extension_Fragment
- : public Packet,
- public Parse_IpV6Extension_Fragment<Packet::iterator, IpV6Extension_Fragment>,
- public PacketRegistryMixin<IpTypes, IpV6Extension_Fragment>
+ : public Packet,
+ public Parse_IpV6Extension_Fragment<Packet::iterator, IpV6Extension_Fragment>,
+ public PacketRegistryMixin<IpTypes, IpV6Extension_Fragment>
{
- using PacketRegistryMixin<IpTypes,IpV6Extension_Fragment>::registerInterpreter;
+ using PacketRegistryMixin<IpTypes,IpV6Extension_Fragment>::registerInterpreter;
public:
///////////////////////////////////////////////////////////////////////////
// Types
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
BOOST_AUTO_UNIT_TEST(ipv6Extension_Fragment_parser)
{
unsigned char data[] = { 59, 0, 0x10, 0x20,
- 0x01, 0x02, 0x03, 0x04 };
+ 0x01, 0x02, 0x03, 0x04 };
typedef unsigned char * iterator;
Parse_IpV6Extension_Fragment<iterator> p (data);
BOOST_AUTO_UNIT_TEST(ipv6Extension_Fragment_packet)
{
// Just for the fun of it, we test a nice chain: A fragment of a fragmented UDP packet
-
- unsigned char data[] = {
- // IP header
- 0x60, 0x00, 0x00, 0x00, // IP Version, class, flow label
- 0, 20, // payload length
- 44, // next header (IPv6 Fragment)
- 32, // hop limit
- 0x20, 0x01, 0, 0, 0, 0, 0, 0, // source ip = 2001::1
- 0, 0, 0, 0, 0, 0, 0, 0x01,
- 0x20, 0x01, 0, 0, 0, 0, 0, 0, // destination ip = 2001::2
- 0, 0, 0, 0, 0, 0, 0, 0x02,
- // IPv6 Fragment header
- 17, // next header (UDP)
- 0, // reserved
- 0x05, 0x00, // fragment offset, last fragment
- 0x01, 0x02, 0x03, 0x04, // id
- // UDP header
- 0x10, 0x00, // source port
- 0x20, 0x00, // destination port
- 0, 12, // length
- 0x00, 0x00, // CRC (no, I won't calculate this one ...)
- // Payload data
- 0x11, 0x12, 0x13, 0x14
+
+ unsigned char data[] = {
+ // IP header
+ 0x60, 0x00, 0x00, 0x00, // IP Version, class, flow label
+ 0, 20, // payload length
+ 44, // next header (IPv6 Fragment)
+ 32, // hop limit
+ 0x20, 0x01, 0, 0, 0, 0, 0, 0, // source ip = 2001::1
+ 0, 0, 0, 0, 0, 0, 0, 0x01,
+ 0x20, 0x01, 0, 0, 0, 0, 0, 0, // destination ip = 2001::2
+ 0, 0, 0, 0, 0, 0, 0, 0x02,
+ // IPv6 Fragment header
+ 17, // next header (UDP)
+ 0, // reserved
+ 0x05, 0x00, // fragment offset, last fragment
+ 0x01, 0x02, 0x03, 0x04, // id
+ // UDP header
+ 0x10, 0x00, // source port
+ 0x20, 0x00, // destination port
+ 0, 12, // length
+ 0x00, 0x00, // CRC (no, I won't calculate this one ...)
+ // Payload data
+ 0x11, 0x12, 0x13, 0x14
};
IpV6Packet::ptr p (Packet::create<IpV6Packet>(data, data + sizeof(data)));
-
+
BOOST_CHECK_EQUAL( p->version(), 6u );
BOOST_CHECK_EQUAL( p->length(), 20u );
BOOST_CHECK_EQUAL( p->nextHeader(), 44u );
BOOST_CHECK_EQUAL( INet6Address(p->source().range()), "2001::1" );
BOOST_CHECK_EQUAL( INet6Address(p->destination().range()), "2001::2" );
BOOST_CHECK( p->next()->is<IpV6Extension_Fragment>() );
-
+
IpV6Extension_Fragment::ptr f (p->next()->as<IpV6Extension_Fragment>());
-
+
BOOST_CHECK_EQUAL( f->nextHeader(), 17u );
BOOST_CHECK_EQUAL( f->fragmentOffset(), 160u );
BOOST_CHECK_EQUAL( f->id(), 0x01020304u );
BOOST_CHECK( f->next()->is<UDPPacket>() );
UDPPacket::ptr u (f->next()->as<UDPPacket>());
-
+
BOOST_CHECK_EQUAL( u->source(), 0x1000u );
BOOST_CHECK_EQUAL( u->destination(), 0x2000u );
BOOST_CHECK_EQUAL( u->length(), 12u );
BOOST_CHECK( u->next()->is<DataPacket>() );
-
+
Packet::iterator i (u->next()->begin());
BOOST_CHECK_EQUAL( Parse_UInt32<Packet::iterator>(i).value(), 0x11121314u );
}
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
Parse_IpV6(Iterator const & i) : ParserBase<Iterator,IpV6Packet>(i) {}
static unsigned bytes() { return 40; }
-
+
///////////////////////////////////////////////////////////////////////////
- typedef Parse_UIntField < 0, 4, Iterator > Parse_Version;
- typedef Parse_UIntField < 4, 12, Iterator > Parse_Class;
- typedef Parse_UIntField < 12, 32, Iterator > Parse_FlowLabel;
- typedef Parse_UInt8 < Iterator > Parse_8bit;
- typedef Parse_UInt16 < Iterator > Parse_16bit;
+ typedef Parse_UIntField < 0, 4, Iterator > Parse_Version;
+ typedef Parse_UIntField < 4, 12, Iterator > Parse_Class;
+ typedef Parse_UIntField < 12, 32, Iterator > Parse_FlowLabel;
+ typedef Parse_UInt8 < Iterator > Parse_8bit;
+ typedef Parse_UInt16 < Iterator > Parse_16bit;
- typedef Parse_Array < 16, Parse_8bit, Iterator > Parse_Addr;
+ typedef Parse_Array < 16, Parse_8bit, Iterator > Parse_Addr;
- Parse_Version version() const { return Parse_Version (this->i() ); }
+ Parse_Version version() const { return Parse_Version (this->i() ); }
Parse_Class trafficClass() const { return Parse_Class (this->i() ); }
- Parse_FlowLabel flowLabel() const { return Parse_FlowLabel (this->i() ); }
- Parse_16bit length() const { return Parse_16bit (this->i() + 4 ); }
+ Parse_FlowLabel flowLabel() const { return Parse_FlowLabel (this->i() ); }
+ Parse_16bit length() const { return Parse_16bit (this->i() + 4 ); }
Parse_8bit nextHeader() const { return Parse_8bit (this->i() + 6 ); }
- Parse_8bit hopLimit() const { return Parse_8bit (this->i() + 7 ); }
+ Parse_8bit hopLimit() const { return Parse_8bit (this->i() + 7 ); }
Parse_Addr source() const { return Parse_Addr (this->i() + 8 ); }
- Parse_Addr destination() const { return Parse_Addr (this->i() + 24 ); }
+ Parse_Addr destination() const { return Parse_Addr (this->i() + 24 ); }
};
class IpV6Packet
- : public Packet,
- public Parse_IpV6<Packet::iterator, IpV6Packet>,
- public PacketRegistryMixin<IpTypes, IpV6Packet>
+ : public Packet,
+ public Parse_IpV6<Packet::iterator, IpV6Packet>,
+ public PacketRegistryMixin<IpTypes, IpV6Packet>
{
- using PacketRegistryMixin<IpTypes,IpV6Packet>::registerInterpreter;
+ using PacketRegistryMixin<IpTypes,IpV6Packet>::registerInterpreter;
public:
///////////////////////////////////////////////////////////////////////////
// Types
friend class Packet;
};
-}
+}
///////////////////////////////hh.e////////////////////////////////////////
//#include "IpV6Packet.cci"
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
BOOST_AUTO_UNIT_TEST(ipV6Packet_parser)
{
unsigned char data[] = { 0x60, 0x12, 0x20, 0x30,
- 0x01, 0x02, 0x03, 0x04,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f };
+ 0x01, 0x02, 0x03, 0x04,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f };
typedef unsigned char * iterator;
Parse_IpV6<iterator> p (data);
BOOST_CHECK_EQUAL( unsigned(p.length()), 0x0102u );
BOOST_CHECK_EQUAL( unsigned(p.nextHeader()), 0x03u );
BOOST_CHECK_EQUAL( unsigned(p.hopLimit()), 0x04u );
- BOOST_CHECK_EQUAL( INet6Address(p.source().range()).address() ,
- "1011:1213:1415:1617:1819:1a1b:1c1d:1e1f" );
- BOOST_CHECK_EQUAL( INet6Address(p.destination().range()).address() ,
- "2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" );
+ BOOST_CHECK_EQUAL( INet6Address(p.source().range()).address() ,
+ "1011:1213:1415:1617:1819:1a1b:1c1d:1e1f" );
+ BOOST_CHECK_EQUAL( INet6Address(p.destination().range()).address() ,
+ "2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" );
}
BOOST_AUTO_UNIT_TEST(ipV6Packet_packet)
{
unsigned char data[] = { 0x60, 0x12, 0x20, 0x30,
- 0x01, 0x02, 0x03, 0x04,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f };
+ 0x01, 0x02, 0x03, 0x04,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f };
IpV6Packet::ptr p (Packet::create<IpV6Packet>(data, data+sizeof(data)));
-
+
BOOST_CHECK_EQUAL( unsigned(p->version()), 0x06u );
BOOST_CHECK_EQUAL( unsigned(p->trafficClass()), 0x01u );
BOOST_CHECK_EQUAL( unsigned(p->flowLabel()), 0x22030u );
BOOST_CHECK_EQUAL( unsigned(p->length()), 0x0102u );
BOOST_CHECK_EQUAL( unsigned(p->nextHeader()), 0x03u );
BOOST_CHECK_EQUAL( unsigned(p->hopLimit()), 0x04u );
- BOOST_CHECK_EQUAL( INet6Address(p->source().range()).address() ,
- "1011:1213:1415:1617:1819:1a1b:1c1d:1e1f" );
- BOOST_CHECK_EQUAL( INet6Address(p->destination().range()).address() ,
- "2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" );
+ BOOST_CHECK_EQUAL( INet6Address(p->source().range()).address() ,
+ "1011:1213:1415:1617:1819:1a1b:1c1d:1e1f" );
+ BOOST_CHECK_EQUAL( INet6Address(p->destination().range()).address() ,
+ "2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" );
BOOST_CHECK( p->next() );
BOOST_CHECK( p->next()->is<DataPacket>() );
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
\section stuff Other Utilities
The pkf also comprises some additional utilities to support the
- development of packet classes.
+ development of packet classes.
The senf::PacketRegistry implements a registry of packets
keyed by an arbitrary type. The registry is used to find a packet
implementing the needed table lookups.
\todo The Packet Libarary really needs a refactoring of the public
- interfaface ...
+ interfaface ...
\idea Add the Handle-Body idiom to the mix with a PacketRef (or
- HeaderRef or InterpreterRef or whatever class). This would
- have members for all the API defined in Packet now. \c
- operator-> would return a parser object to interpret the
- data. This would make awayy with the inheritance relationship
- ...
+ HeaderRef or InterpreterRef or whatever class). This would
+ have members for all the API defined in Packet now. \c
+ operator-> would return a parser object to interpret the
+ data. This would make awayy with the inheritance relationship
+ ...
\idea Templating the parsers on the iterator type does not
- introduce additional coupling (because of the inlining) but
- looking at it after the fact it looks like severe overdesign
- and it does introduce some problems (e.g. rebind and all this
- entails). If we just implement all parsers for
- Packet::byte_iterator they are no tmplates any more which
- should simplify things a log.
+ introduce additional coupling (because of the inlining) but
+ looking at it after the fact it looks like severe overdesign
+ and it does introduce some problems (e.g. rebind and all this
+ entails). If we just implement all parsers for
+ Packet::byte_iterator they are no tmplates any more which
+ should simplify things a log.
\idea we need some better and automatic checking on data access
- especially after data has changed. Idea 1: give the parser the
- end iterator as additional member. Enforce, that all parsers
- must ultimately be based on ParseInt and have ParseInt check
- against end() at construction time. Idea 2: add a dirty flag
- to the interpreters. Set this flag whenever the packet is
- changed and recall check() in operator-> of the PacketRef
- object if the packet is dirty. Maybe we need both and make
- them tunable.
+ especially after data has changed. Idea 1: give the parser the
+ end iterator as additional member. Enforce, that all parsers
+ must ultimately be based on ParseInt and have ParseInt check
+ against end() at construction time. Idea 2: add a dirty flag
+ to the interpreters. Set this flag whenever the packet is
+ changed and recall check() in operator-> of the PacketRef
+ object if the packet is dirty. Maybe we need both and make
+ them tunable.
*/
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// mode: flyspell
// mode: auto-fill
-// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
senf::impl::PacketImpl::appendInterpreter(Packet * p)
{
BOOST_ASSERT( p->impl_ == 0 );
-
+
this->refcount_ += p->refcount_;
SATCOM_PKF_REFC_MSG("] PacketImpl::appendInterpreter (" << this << "): refcount_ = " << refcount_ << "\n");
p->impl_ = this;
}
prefix_ void senf::impl::PacketImpl::packet_release(Packet * p)
-{
+{
bool del (p->release());
if (p->impl_ && p->impl_->release())
// In this case, del is certainly false here. p might
if (this->parsed_)
return ptr(0);
/* \fixme v_nextInterpreter return bool? new Interpreter to be
- added ? hmm ... this however is quite suboptimal ... */
+ added ? hmm ... this however is quite suboptimal ... */
this->v_nextInterpreter();
this->parsed_ = true;
n = boost::next(this->self_);
size_type sz(last-first);
BOOST_ASSERT( index >= begin_ && index < end_ && sz <= end_-index );
/** \fixme Here we should assert, that no bytes belonging to the
- next iterator are deleted ... */
+ next iterator are deleted ... */
impl_->data_.erase(first,last);
impl_->updateIterators(index,-sz,self_,INSIDE);
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// PacketImpl::add_ref and PacketImpl::release are only called from
// intrusive_ptr_add_ref and intrusive_ptr_release
prefix_ void senf::impl::PacketImpl::add_ref()
-{
+{
++refcount_;
SATCOM_PKF_REFC_MSG("] PacketImpl::add_ref (" << this << "): refcount_ = " << refcount_ << "\n");
}
prefix_ bool senf::impl::PacketImpl::release()
-{
+{
BOOST_ASSERT( refcount_ > 0 );
--refcount_;
SATCOM_PKF_REFC_MSG("] PacketImpl::release (" << this << "): refcount_ = " << refcount_ << "\n");
*/
// These methods are called by the user codes Packet::ptr's. They
-// refcount both the Packet and the owning PacketImpl.
+// refcount both the Packet and the owning PacketImpl.
prefix_ void senf::intrusive_ptr_add_ref(Packet const * p)
{
impl::PacketImpl::packet_add_ref(p);
prefix_ senf::Packet::~Packet()
{
/** \fixme This is bad ... we cannot check this since this
- assertion fails at the moment if the Packet constructor throws
- ... hrmpf ... we really need to initialize refcount_ to 0 and
- remove the 'false' argument to the ptr constructor in create */
+ assertion fails at the moment if the Packet constructor throws
+ ... hrmpf ... we really need to initialize refcount_ to 0 and
+ remove the 'false' argument to the ptr constructor in create */
// BOOST_ASSERT( !this->refcount_ && !this->impl_ );
SATCOM_PKF_REFC_MSG("] Packet::~Packet (" << this << ")\n");
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
senf::Packet::create(Packet::ptr payload)
{
/** \todo should I instead of using head() throw away all
- interpreters before payload? ... probably yes ... */
+ interpreters before payload? ... probably yes ... */
payload->insert(payload->head()->begin(),min_bytes<OuterPacket>(),0);
typename ptr_t<OuterPacket>::ptr p (new OuterPacket(PacketOp_set(payload->impl_)));
p->init();
throw TruncatedPacketException();
typename ptr_t<OtherPacket>::ptr p (
new OtherPacket(PacketOp_register(begin-impl_->data_.begin(),
- end-impl_->data_.begin(),
- this)),
+ end-impl_->data_.begin(),
+ this)),
false);
return p;
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
{
SATCOM_PKF_REFC_MSG("] Packet::Packet (" << this << "): refcount_ = 1\n");
/** \fixme This is not exception safe, if an exception is thrown in
- the derived class constuctor, the effects of this call must be
- undone which is not possible in a simple way. */
+ the derived class constuctor, the effects of this call must be
+ undone which is not possible in a simple way. */
arg(this);
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// ////////////////////////////hh.p////////////////////////////////////////
namespace senf {
-
+
namespace impl { template <class OtherPacket> class PkReg_EntryImpl; }
namespace impl { class PacketImpl; }
/** \brief Basic interface to all packet facades
\section packet_overview Overview
-
+
This class is the base class of all Packets. It implements the
generic Packet interface and provides the packet management
framework. senf::Packet manages the necessary memory
automatic.
\image html structure.png Overview
-
+
Internally, every Packet references a PacketImpl instance which
manages the raw packet data and the interpreter list. This raw
data is interpreted by the concrete Packet derived class
type (i.e. EthernetPacket or UDPPacket).
Packet provides several interfaces:
-
+
- Creation of Packet instances: create()
- Access to the chain of interpreters: next(), prev(), head(),
- You must implement a static check() method which validates
a byte region as your new Packet
- \code
- class ExamplePacket
+ \code
+ class ExamplePacket
: public senf::Packet
{
public:
{
// check does not need to be implemented here, it is
- // inherited from the parser
+ // inherited from the parser
private:
template <class InputIterator>
///////////////////////////////////////////////////////////////////////////
///\name Types
///@{
-
+
/** \brief smart pointer template for all Packet classes
-
+
This struct is just a template typedef. It defines the
smart pointer used for all Packet classes.
*/
Every derived class \e must redeclare this member for it's
derived type:
- \code
+ \code
typedef ptr_t<DerivedClass>::ptr ptr
\endcode
*/
- typedef ptr_t<Packet>::ptr ptr;
+ typedef ptr_t<Packet>::ptr ptr;
typedef raw_container::iterator iterator; //!< raw data iterator
typedef raw_container::size_type size_type;
typedef raw_container::difference_type difference_type;
///@{
/** \brief create new Packet
-
+
This method is used to create a new Packet. All Packet
instances are created via this method, they are \e never
created directly from the Packet derived class.
///\name Interpreter chain
///@{
-
+
/** \brief get next packet from the interpreter chain
\return smart pointer to next packet or 0 if last packet */
ptr next() const;
/** \brief get last packet of the interpreter chain
\return smart pointer to last packet */
ptr last() const;
-
+
/** \brief first packet of given type after the current packet
\return smart pointer to first following packet of type \a
OtherPacket or 0, if no such packet exists */
/** \brief check, wether the packet is of the given type
\return true, if packt is of type \a OtherPacket, false
otherwise */
- template <class OtherPacket> bool is() const;
+ template <class OtherPacket> bool is() const;
/** \brief cast packet pointer to the given type
\return a properly cast smart pointer if packet is of type
\a OtherPacket. Otherwise return 0 */
- template <class OtherPacket> typename ptr_t<OtherPacket>::ptr as();
+ template <class OtherPacket> typename ptr_t<OtherPacket>::ptr as();
/** \brief replace current packet interpreter
This method will \e replace the current packet facade in
the interpreter list with a new interpreter given by \a
- OtherPacket.
+ OtherPacket.
\attention This invalidates the packet instance \e
this. You must ensure, not to use the Packet instance any
///@{
/** \brief begin interator of raw packet data
-
+
This iterator allows access to the raw data interpreted by
the packet facade. This \e includes any header possibly
interpreted by the derived packet instance. To access the
data */
iterator begin() const;
/** \brief past-the-end iterator of raw packet data
-
+
This iterator allows access to the raw data interpreted by
the packet facade. This \e includes any header possibly
interpreted by the derived packet instance. To access the
derived packet instance. This method is mostly to be used
by the derived class implementation and their helper
classes. */
- template <class InputIterator>
+ template <class InputIterator>
void insert(iterator pos, InputIterator f, InputIterator l, Whence whence = AUTO);
/** \brief erase single byte
///@{
/** \brief create new interpreter facade for an existing packet
-
+
This constructor is called, when a new interpreter is to
be added to the interpreter chain. The constructor is
called indirectly from registerInterpreter() or
template <class Operation>
Packet(Operation const & arg);
virtual ~Packet();
-
+
private:
/** \brief create next packet interpreter
bool release();
bool unlink();
- struct PacketOp_register;
- friend class PacketOp_register;
+ struct PacketOp_register;
+ friend class PacketOp_register;
void i_registerInterpreter(Packet * p) const;
- struct PacketOp_replace;
- friend class PacketOp_replace;
+ struct PacketOp_replace;
+ friend class PacketOp_replace;
void i_replaceInterpreter(Packet * p);
- struct PacketOp_set;
- friend class PacketOp_set;
+ struct PacketOp_set;
+ friend class PacketOp_set;
void i_setInterpreter(impl::PacketImpl * i);
private:
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
size_type e;
const Packet * p;
- PacketOp_register(size_type b_, size_type e_, const Packet * p_)
- : b(b_), e(e_), p(p_) {}
+ PacketOp_register(size_type b_, size_type e_, const Packet * p_)
+ : b(b_), e(e_), p(p_) {}
size_type begin() const { return b; }
size_type end() const { return e; }
{ p->i_registerInterpreter(self); }
};
-struct senf::Packet::PacketOp_replace
+struct senf::Packet::PacketOp_replace
{
Packet * p;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
throw TruncatedPacketException();
typename ptr_t<OtherPacket>::ptr p (
new OtherPacket(PacketOp_replace(this),
- BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a ) ),
+ BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a ) ),
false);
return p;
}
if (!OtherPacket::check(begin,end))
throw TruncatedPacketException();
typename ptr_t<OtherPacket>::ptr p (
- new OtherPacket(PacketOp_register(begin-impl_->data_.begin(),
- end-impl_->data_.begin(),
- this),
- BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a) ),
+ new OtherPacket(PacketOp_register(begin-impl_->data_.begin(),
+ end-impl_->data_.begin(),
+ this),
+ BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a) ),
false);
return p;
}
///////////////////////////////////////////////////////////////////////////
// Packet::create declaration
-template < class OtherPacket, class InputIterator,
+template < class OtherPacket, class InputIterator,
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A) >
static typename senf::Packet::ptr_t<OtherPacket>::ptr create(
InputIterator b, InputIterator e,
///////////////////////////////////////////////////////////////////////////
// Packet::create implementation
-template < class OtherPacket, class InputIterator,
+template < class OtherPacket, class InputIterator,
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A) >
typename senf::Packet::ptr_t<OtherPacket>::ptr senf::Packet::create(
InputIterator b, InputIterator e,
if (!OtherPacket::check(impl->data_.begin(), impl->data_.end()))
throw TruncatedPacketException();
typename ptr_t<OtherPacket>::ptr p (
- new OtherPacket(PacketOp_set(impl.get()),
- BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a) ),
+ new OtherPacket(PacketOp_set(impl.get()),
+ BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a) ),
false);
return p;
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
}
}
-
+
BOOST_AUTO_UNIT_TEST(Packet_DataPacket)
{
Packet::ptr p (Packet::create<DataPacket>(data, data+sizeof(data)));
BOOST_CHECK( compare(p->begin_header(), p->end_header()) );
BOOST_CHECK_EQUAL( p->trailer_len(), 6u );
BOOST_CHECK( compare(p->begin_trailer(), p->end_trailer(), sizeof(data)-6) );
-
+
// check the first packet in the interpreter chain
BOOST_CHECK_EQUAL( p->head(), p );
BOOST_CHECK( !p->prev() );
BOOST_REQUIRE( p->next() );
BOOST_CHECK( p->next()->is<DataPacket>() );
BOOST_CHECK(( !p->next()->is< GenericPacket<4,6> >() ));
-
+
// check the contents of the second interpreter
BOOST_CHECK_EQUAL( p->next()->size(), sizeof(data)-10 );
BOOST_CHECK( compare(p->next()->begin(), p->next()->end(), 4) );
// We need require here. If this fails, p->last() will probably
// run into an endless loop ...
BOOST_REQUIRE( !p->next()->next() );
- BOOST_CHECK_EQUAL( p->next(), p->last() );
+ BOOST_CHECK_EQUAL( p->next(), p->last() );
}
BOOST_AUTO_UNIT_TEST(Packet_Reinterpret)
{
Packet::ptr p (Packet::create< GenericPacket<4,4> >(data, data+sizeof(data)));
-
+
BOOST_CHECK( p->next()->is<DataPacket>() );
p->next()->reinterpret< GenericPacket<6> >();
BOOST_CHECK( p->next()->is< GenericPacket<6> >() );
p = p->reinterpret< GenericPacket<8,2> >();
BOOST_REQUIRE( p->next() );
BOOST_CHECK( p->next()->is<DataPacket>() );
-
+
BOOST_CHECK_EQUAL( p->next()->size(), sizeof(data)-10 );
BOOST_CHECK( compare(p->next()->begin(), p->next()->end(), 8) );
}
{
Packet::ptr p (Packet::create< GenericPacket<7,3> >(data, data+sizeof(data)));
p->next()->reinterpret< GenericPacket<4> >();
-
+
BOOST_CHECK_EQUAL( p->size(), 20u );
BOOST_CHECK_EQUAL( p->next()->size(), 10u );
BOOST_CHECK_EQUAL( p->next()->next()->size(), 6u );
BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 11) );
p->next()->erase( p->next()->begin()+2, p->next()->begin()+8 );
-
+
BOOST_CHECK_EQUAL( p->size(), 20u );
BOOST_CHECK_EQUAL( p->next()->size(), 10u );
BOOST_CHECK_EQUAL( p->next()->next()->size(), 6u );
BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 11) );
p->next()->next()->insert(p->next()->begin()+5, data, data+4);
-
+
BOOST_CHECK_EQUAL( p->size(), 24u );
BOOST_CHECK_EQUAL( p->next()->size(), 14u );
BOOST_CHECK_EQUAL( p->next()->next()->size(), 10u );
BOOST_CHECK( compare(p->begin()+10, p->end(), 12) );
p->erase(p->begin()+5, p->end());
-
+
BOOST_CHECK_EQUAL( p->size(), 5u );
BOOST_CHECK_EQUAL( p->next()->size(), 0u );
BOOST_CHECK_EQUAL( p->next()->next()->size(), 0u );
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
#define prefix_
///////////////////////////////PacketRegistry..p////////////////////////////////////////
-senf::impl::PkReg_EntryImpl<senf::DataPacket>
+senf::impl::PkReg_EntryImpl<senf::DataPacket>
senf::impl::pkreg_dataEntry;
///////////////////////////////PacketRegistry..e////////////////////////////////////////
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
The PacketRegistry provides a generic facility to associate an
arbitrary key with Packets. Example keys are Ethertype or IP
protocols.
-
+
Every PacketRegistry is identified by a type tag:
\code
struct SomeTag {
Normally, packet classes are registered statically and not
procedurally. To this end, the RegistrationProxy is provided:
\code
- PacketRegistry<SomeTag>::RegistrationProxy<SomePacket>
+ PacketRegistry<SomeTag>::RegistrationProxy<SomePacket>
registerSomePacket (key_of_somePacket);
\endcode
This global variable declaration will register \c SomePacket
facades. This is further supported by the PacketRegistryMixin
class.
- \todo Add parameterless create() method
+ \todo Add parameterless create() method
*/
template <class Tag>
class PacketRegistry
public:
/** \brief Statically register a packet type in a PacketRegistry
- \fixme This fails to work within a library since the linker will
- remove all unused object files ...
+ \fixme This fails to work within a library since the linker will
+ remove all unused object files ...
*/
template <class OtherPacket>
struct RegistrationProxy
{
RegistrationProxy(typename Tag::key_t key);
};
-
+
/** \brief Register new packet type
-
+
Register \c OtherPacket in the packet registry \c Tag
under the given \c key.
static void registerPacket(typename Tag::key_t key);
/** \brief Find key of a packet
-
+
Return the key of \c OtherPacket as registered in the \c
Tag registry
*/
template <class InputIterator>
static Packet::ptr create(typename Tag::key_t key, InputIterator b, InputIterator e);
-
+
private:
typedef impl::PacketRegistryImpl<typename Tag::key_t> Registry;
static Registry & registry();
-
+
template <class T, class D> friend class PacketRegistryMixin;
};
{
protected:
/** \brief add interpreter to interpreter chain
-
+
This method is used by v_nextInterpreter() to add a new
interpreter to the interpreter chain (see the Packet
reference for more). Instead of specifying the type of
packet to use as a template argument it is specified using
the \c key value from the \c Tag registry
*/
- void registerInterpreter(typename Tag::key_t key,
+ void registerInterpreter(typename Tag::key_t key,
Packet::iterator b, Packet::iterator e) const;
};
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
struct PkReg_Entry {
virtual ~PkReg_Entry() {}
- virtual void registerInterpreter(Packet const * p,
+ virtual void registerInterpreter(Packet const * p,
Packet::iterator b, Packet::iterator e) = 0;
virtual Packet::ptr reinterpret(Packet * p) = 0;
};
public:
///////////////////////////////////////////////////////////////////////////
// Types
-
+
typedef KeyType key_t;
typedef impl::PkReg_Entry Entry;
-
+
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
typedef std::string key_t;
};
- class BasePacket
+ class BasePacket
: public Packet, public PacketRegistryMixin<BaseTag,BasePacket>
{
using PacketRegistryMixin<BaseTag,BasePacket>::registerInterpreter;
public:
typedef ptr_t<BasePacket>::ptr ptr;
typedef iterator byte_iterator;
-
+
typedef Parse_UInt16<iterator> Parse_Type;
-
+
Parse_Type type() const { return Parse_Type(begin()); }
static bool check(iterator b, iterator e) { return true; }
-
+
private:
template <class Arg>
BasePacket(Arg const & arg) : Packet(arg) {}
public:
typedef ptr_t<FooPacket>::ptr ptr;
typedef iterator byte_iterator;
-
+
static bool check(iterator b, iterator e) { return true; }
private:
public:
typedef ptr_t<BarPacket>::ptr ptr;
typedef iterator byte_iterator;
-
+
static bool check(iterator b, iterator e) { return true; }
private:
PacketRegistry<StringTag>::RegistrationProxy<FooPacket> registerFoo ("foo");
PacketRegistry<StringTag>::RegistrationProxy<BarPacket> registerBar ("bar");
}
-
+
}
BOOST_AUTO_UNIT_TEST(packetRegistry_test)
{
unsigned char data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
-
+
{
BasePacket::ptr p (Packet::create<BasePacket>(data, data+sizeof(data)));
BOOST_CHECK( p->next()->is<DataPacket>() );
BasePacket::ptr p (Packet::create<BasePacket>(data, data+sizeof(data)));
BOOST_CHECK( p->next()->is<BarPacket>() );
}
-
+
data[0] = 0x01;
{
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <unsigned elements, class Parser, class Iterator, class IPacket>
prefix_
senf::Parse_Array<elements,Parser,Iterator,IPacket>::Parse_Array(Iterator const & i)
- : ParserBase<Iterator,IPacket>(i)
+ : ParserBase<Iterator,IPacket>(i)
{}
template <unsigned elements, class Parser, class Iterator, class IPacket>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace senf {
-
+
namespace impl { template <class,class> class Parse_Array_iterator; }
/* Parse_Array has the external interface of a container class
///////////////////////////////////////////////////////////////////////////
// Parser interface
- template <class I=nil, class P=nil>
+ template <class I=nil, class P=nil>
struct rebind { typedef Parse_Array<elements,Parser,I,P> parser; };
typedef Iterator byte_iterator;
Parse_Array();
explicit Parse_Array(Iterator const & i);
-
+
static unsigned bytes();
bool check(Iterator const & e) const;
void init() const;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
public:
Parse_Array_iterator();
explicit Parse_Array_iterator(Iterator const & i);
-
+
// Needed to elide the []-proxy of iterator_facade
Parser operator[](int i) const;
Iterator raw() const;
protected:
-
+
private:
friend class boost::iterator_core_access;
-
+
Parser dereference() const;
bool equal(Parse_Array_iterator const & other) const;
int distance_to(Parse_Array_iterator const & other) const;
void increment();
void decrement();
void advance(int n);
-
+
Iterator i_;
-};
+};
///////////////////////////////ih.e////////////////////////////////////////
#endif
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class Iterator=nil, class IPacket=nil>
struct Parse_Int8
- : public impl::ParseIntOps<Parse_Int8<Iterator,IPacket>,boost::int8_t>,
+ : public impl::ParseIntOps<Parse_Int8<Iterator,IPacket>,boost::int8_t>,
public ParserBase<Iterator,IPacket>
- {
+ {
template <class I=nil, class P=nil>
struct rebind { typedef Parse_Int8<I,P> parser; };
typedef Iterator byte_iterator;
template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt8
- : public impl::ParseIntOps<Parse_UInt8<Iterator,IPacket>,boost::uint8_t>,
+ : public impl::ParseIntOps<Parse_UInt8<Iterator,IPacket>,boost::uint8_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
typedef Iterator byte_iterator;
static unsigned bytes() { return 1; }
-
+
Parse_UInt8() {}
explicit Parse_UInt8(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
template <class Iterator=nil, class IPacket=nil>
struct Parse_Int16
- : public impl::ParseIntOps<Parse_Int16<Iterator,IPacket>,boost::int16_t>,
+ : public impl::ParseIntOps<Parse_Int16<Iterator,IPacket>,boost::int16_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt16
- : public impl::ParseIntOps<Parse_UInt16<Iterator,IPacket>,boost::uint16_t>,
+ : public impl::ParseIntOps<Parse_UInt16<Iterator,IPacket>,boost::uint16_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
template <class Iterator=nil, class IPacket=nil>
struct Parse_Int24
- : public impl::ParseIntOps<Parse_Int24<Iterator,IPacket>,boost::int32_t>,
+ : public impl::ParseIntOps<Parse_Int24<Iterator,IPacket>,boost::int32_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
typedef boost::int32_t value_type;
- value_type value() const {
+ value_type value() const {
value_type v (impl::parse_uint24(this->i())); return v&0x800000 ? v|0xff000000 : v; }
void value(value_type v) { impl::write_uint24(this->i(),v); }
Parse_Int24 const & operator= (value_type other) { value(other); return *this; }
template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt24
- : public impl::ParseIntOps<Parse_UInt24<Iterator,IPacket>,boost::uint32_t>,
+ : public impl::ParseIntOps<Parse_UInt24<Iterator,IPacket>,boost::uint32_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
template <class Iterator=nil, class IPacket=nil>
struct Parse_Int32
- : public impl::ParseIntOps<Parse_Int32<Iterator,IPacket>,boost::int32_t>,
+ : public impl::ParseIntOps<Parse_Int32<Iterator,IPacket>,boost::int32_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt32
- : public impl::ParseIntOps<Parse_UInt32<Iterator,IPacket>,boost::uint32_t>,
+ : public impl::ParseIntOps<Parse_UInt32<Iterator,IPacket>,boost::uint32_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
template <unsigned start, unsigned end, class Iterator=nil, class IPacket=nil>
struct Parse_IntField
- : public impl::ParseIntOps<Parse_IntField<start,end,Iterator,IPacket>,boost::int32_t>,
+ : public impl::ParseIntOps<Parse_IntField<start,end,Iterator,IPacket>,boost::int32_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
typedef boost::int32_t value_type;
- value_type value() const {
+ value_type value() const {
value_type v (impl::parse_bitfield<Iterator,start,end>::parse(this->i()));
return v&boost::high_bit_mask_t<end-start-1>::high_bit ?
v | ~boost::low_bits_mask_t<end-start>::sig_bits : v;
template <unsigned start, unsigned end, class Iterator=nil, class IPacket=nil>
struct Parse_UIntField
- : public impl::ParseIntOps<Parse_UIntField<start,end,Iterator,IPacket>,boost::uint32_t>,
+ : public impl::ParseIntOps<Parse_UIntField<start,end,Iterator,IPacket>,boost::uint32_t>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
template <unsigned bit, class Iterator=nil, class IPacket=nil>
struct Parse_Flag
- : public impl::ParseIntOps<Parse_Flag<bit,Iterator,IPacket>,bool>,
+ : public impl::ParseIntOps<Parse_Flag<bit,Iterator,IPacket>,bool>,
public ParserBase<Iterator,IPacket>
{
template <class I=nil, class P=nil>
typedef bool value_type;
value_type value() const { return this->i()[bit/8] & (1<<(7-(bit%8))); }
- void value(value_type v) {
+ void value(value_type v) {
if (v) this->i()[0] |= 1<<(7-(bit%8));
else this->i()[0] &= ~(1<<(7-(bit%8)));
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace senf {
namespace impl {
-
+
///////////////////////////////////////////////////////////////////////////
// Integer operators
operator Value () const { return derived().value(); }
# define unary(op) \
- Value operator op () const { return op derived().value(); }
+ Value operator op () const { return op derived().value(); }
# define mutator(op) \
template <class Other> Derived const & operator op ## = (Other other) \
{ derived().value( derived().value() op other ); return derived(); }
# undef unary
# undef mutator
-
+
Derived const & operator ++ ()
{ derived().value( derived.value()+1 ); return derived(); }
Derived const & operator -- ()
Derived & derived() { return *static_cast<Derived *>(this); }
Derived const & derived() const { return *static_cast<Derived const *>(this); };
};
-
+
///////////////////////////////////////////////////////////////////////////
// Network byte order integer extraction
-
+
template <class Iterator>
boost::uint16_t parse_uint16(Iterator const & i)
{
{
static boost::uint32_t parse(Iterator const & i) {
return ( ( ( parse_uint32(i+offset+1)>>(40-end) ) // Beware of sign extension !!
- & boost::low_bits_mask_t<32-(40-end)>::sig_bits )
+ & boost::low_bits_mask_t<32-(40-end)>::sig_bits )
| (i[offset]<<(32-(40-end))) )
& boost::low_bits_mask_t<end-start>::sig_bits;
}
static void write(Iterator const & i, boost::uint32_t v) {
- write_uint32(i+offset+1,
+ write_uint32(i+offset+1,
(parse_uint32(i+offset+1) & ~(boost::low_bits_mask_t<end-8>::sig_bits<<(40-end)))
| ((v & boost::low_bits_mask_t<end-8>::sig_bits) << (40-end)));
i[offset] = (i[offset] & ~(boost::low_bits_mask_t<8-start>::sig_bits))
}
static void write(Iterator const & i, boost::uint32_t v) {
- write_uint32(i+offset,
+ write_uint32(i+offset,
(parse_uint32(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(32-end)))
| ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (32-end)));
}
}
static void write(Iterator const & i, boost::uint32_t v) {
- write_uint24(i+offset,
+ write_uint24(i+offset,
(parse_uint24(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(24-end)))
| ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (24-end)));
}
}
static void write(Iterator const & i, boost::uint32_t v) {
- write_uint16(i+offset,
+ write_uint16(i+offset,
(parse_uint16(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(16-end)))
| ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (16-end)));
}
struct parse_bitfield_i<Iterator, offset, 0, start, end>
{
static boost::uint32_t parse(Iterator const & i) {
- return ( i[offset]>>(8-end) )
+ return ( i[offset]>>(8-end) )
& boost::low_bits_mask_t<end-start>::sig_bits;
}
};
template <class Iterator, unsigned start, unsigned end>
- struct parse_bitfield
+ struct parse_bitfield
: public parse_bitfield_i<Iterator,start/8,(end-1)/8-start/8,start%8,end-8*(start/8)>
{};
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// 011000111101011101011010001100011010010001000110
unsigned char data[] = { 0x63, 0xd7, 0x5a, 0x31, 0xa4, 0x46 };
typedef unsigned char * iterator;
-
+
// 1 byte
BOOST_CHECK_EQUAL((Parse_UIntField<2,7,iterator>(data).value()), 17u);
BOOST_CHECK_EQUAL((Parse_IntField<2,7,iterator>(data).value()), -15);
Parse_Int8<iterator>(data).value(0x2f);
BOOST_CHECK_EQUAL( data[0], 0x2f );
-
+
Parse_Int16<iterator>(data).value(0xa341);
BOOST_CHECK_EQUAL( data[0], 0xa3 );
BOOST_CHECK_EQUAL( data[1], 0x41 );
BOOST_CHECK_EQUAL( data[1], 0xdc );
BOOST_CHECK_EQUAL( data[2], 0xba );
BOOST_CHECK_EQUAL( data[3], 0x98 );
-
+
Parse_IntField<2,6,iterator>(data).value(0x3);
BOOST_CHECK_EQUAL( data[0], 0xce );
BOOST_CHECK_EQUAL( data[1], 0xdc );
BOOST_CHECK_EQUAL( (Parse_UIntField<4,34,iterator>(data).value()), 0x268ad497u );
}
-BOOST_AUTO_UNIT_TEST(parseInt_operators)
+BOOST_AUTO_UNIT_TEST(parseInt_operators)
{
unsigned char data[] = { 0x63, 0xd7, 0x5a, 0x31, 0xa4, 0x46 };
}
namespace {
-
+
template < class P >
- class TestPacket
+ class TestPacket
: public Packet, public P::template rebind< Packet::iterator,TestPacket<P> >::parser
{
public:
typedef typename P::template rebind<Packet::iterator,TestPacket>::parser parser;
typedef typename ptr_t<TestPacket>::ptr ptr;
-
+
static bool check(iterator b, iterator e) { return true; }
private:
template <class Arg>
- TestPacket(Arg const & arg)
+ TestPacket(Arg const & arg)
: Packet(arg) {}
virtual void v_nextInterpreter() const {}
- virtual void v_finalize() {}
+ virtual void v_finalize() {}
virtual void v_dump(std::ostream &) const {}
friend class Packet;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
{}
template <class Parser, class Sentinel, class Iterator>
-prefix_
+prefix_
senf::impl::Parse_ListS_iterator<Parser,Sentinel,Iterator>::
Parse_ListS_iterator(Iterator const & i)
: i_(i), atEnd_(false)
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
element and a (non-const) reference to the state which it may
update. The Parse_ListS constructor must take an arbitrary number
of additional arguments which are forwarded to the state
- initialization.
-
+ initialization.
+
This structure makes it simple to optimize away the overhead if
the state type is void. If we would always instantiate the
sentinel, this will always take up space.
template <class Parser, class Sentinel, class Container> class Parse_ListS_wrapper;
- namespace impl {
- template <class Parser, class Sentinel, class Container> class Parse_ListS_iterator;
+ namespace impl {
+ template <class Parser, class Sentinel, class Container> class Parse_ListS_iterator;
}
template <class Parser, class Sentinel, class Iterator=nil, class IPacket=nil>
///////////////////////////////////////////////////////////////////////////
// Parser interface
- template <class I=nil, class P=nil>
+ template <class I=nil, class P=nil>
struct rebind { typedef Parse_ListS<Parser,Sentinel,I,P> parser; };
typedef Iterator byte_iterator;
-
+
Parse_ListS();
Parse_ListS(Iterator const & i);
-
+
unsigned bytes() const;
bool check(Iterator const & e) const;
void init() const;
};
/** \brief
-
+
Holds a reference to the container !
*/
template <class Parser, class Sentinel, class Container>
///\name Mutators
///@{
- template <class Value> void insert(iterator pos, Value const & t);
- template <class Value> void insert(iterator pos, size_type n, Value const & t);
- template <class InputIterator> void insert(iterator pos, InputIterator f, InputIterator l);
-
- void erase(iterator pos, size_type n=1);
- void erase(iterator f, iterator l);
- void clear();
+ template <class Value> void insert(iterator pos, Value const & t);
+ template <class Value> void insert(iterator pos, size_type n, Value const & t);
+ template <class InputIterator> void insert(iterator pos, InputIterator f, InputIterator l);
+
+ void erase(iterator pos, size_type n=1);
+ void erase(iterator f, iterator l);
+ void clear();
///@}
protected:
private:
-
+
size_type i_;
Container & container_;
};
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
public:
Parse_ListS_iterator();
explicit Parse_ListS_iterator(Iterator const & i);
-
+
Iterator raw() const;
-
+
private:
friend class boost::iterator_core_access;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x00 };
typedef unsigned char * iterator;
typedef Parse_ListS<Parse_UInt8<>,Sentinel_IsZero<unsigned char>,iterator> Parse_UInt8ListS;
-
+
Parse_UInt8ListS l (data);
Parse_UInt8ListS::iterator i (l.begin());
Parse_UInt8ListS::iterator e (l.end());
struct rebind { typedef Parse_LVec<Parser,SizeParser,I,P> parser; };
typedef typename SizeParser::template rebind<Iterator>::parser sizeParser;
- Parse_LVec(Iterator const & i)
+ Parse_LVec(Iterator const & i)
: Parse_Vector<Parser,SizeParser,Iterator,IPacket>(sizeParser(i),i+sizeParser::bytes())
{}
-
+
unsigned bytes() const
{ return this->Parse_Vector<Parser,SizeParser,Iterator,IPacket>::bytes() + sizeParser::bytes(); }
bool check(Iterator const & e) const
++i;
}
BOOST_CHECK( i==e );
-
+
BOOST_CHECK_EQUAL( l.size(), 3u );
BOOST_CHECK_EQUAL( l.bytes(), 13u );
BOOST_CHECK( !l.empty() );
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
size_type ix(pos.raw()-container_.begin());
shift(pos,n);
typename Container::iterator j (container_.begin()+ix);
- for (; n; --n, j+=Parser::bytes())
+ for (; n; --n, j+=Parser::bytes())
Parser(j).value(t);
}
InputIterator l)
{
/** \fixme This might be horribly inefficient ... we need to
- specialize for random_access and forward iterators, where we
- can count the distance */
+ specialize for random_access and forward iterators, where we
+ can count the distance */
size_type ix(pos.raw()-container_.begin());
for (;f!=l;++f) {
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class Parser, class SizeParser, class Iterator, class IPacket>
prefix_ senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::
Parse_Vector(SizeParser const & size)
- : size_(size)
+ : size_(size)
{}
template <class Parser, class SizeParser, class Iterator, class IPacket>
prefix_ senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::
Parse_Vector(size_parser const & size, Iterator const & i)
- : ParserBase<Iterator,IPacket>(i), size_(size)
+ : ParserBase<Iterator,IPacket>(i), size_(size)
{}
template <class Parser, class SizeParser, class Iterator, class IPacket>
}
template <class Parser, class SizeParser, class Iterator, class IPacket>
-prefix_
+prefix_
typename senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::iterator
senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::begin()
const
}
template <class Parser, class SizeParser, class Iterator, class IPacket>
-prefix_
+prefix_
typename senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::iterator
senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::end()
const
}
template <class Parser, class SizeParser, class Iterator, class IPacket>
-prefix_
+prefix_
typename senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::range_type
senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::range()
const
}
template <class Parser, class SizeParser, class Iterator, class IPacket>
-prefix_
+prefix_
typename senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::range_type
senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::value()
const
}
template <class Parser, class SizeParser, class Iterator, class IPacket>
-prefix_
+prefix_
typename senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::value_type
senf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::operator[](difference_type i)
const
prefix_ senf::Parse_Vector_wrapper<Parser,SizeParser,Container>::
Parse_Vector_wrapper(Parse_Vector<P,SP,I,IP> const & vector, Container & container)
: i_(vector.i()-container.begin()), size_i_(vector.size_.i()-container.begin()),
- container_(container)
+ container_(container)
{}
template <class Parser, class SizeParser, class Container>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////////////////////////////////////////////////
// Parser interface
- template <class I=nil, class P=nil>
+ template <class I=nil, class P=nil>
struct rebind { typedef Parse_Vector<Parser,SizeParser,I,P> parser; };
typedef Iterator byte_iterator;
-
+
explicit Parse_Vector(SizeParser const & size);
Parse_Vector(size_parser const & size, Iterator const & i);
-
+
unsigned bytes() const;
void check(Iterator const & e) const;
void init() const;
private:
size_parser size_;
-
+
template <class P, class SP, class C> friend class Parse_Vector_wrapper;
};
/** \brief
-
+
Holds a reference to the container !
*/
template <class Parser, class SizeParser, class Container>
///\name Mutators
///@{
- void shift(iterator pos, size_type n=1);
+ void shift(iterator pos, size_type n=1);
template <class Value>
- void insert(iterator pos, Value const & t);
+ void insert(iterator pos, Value const & t);
template <class Value>
- void insert(iterator pos, size_type n, Value const & t);
+ void insert(iterator pos, size_type n, Value const & t);
template <class InputIterator>
- void insert(iterator pos, InputIterator f, InputIterator l);
-
- void erase(iterator pos, size_type n=1);
- void erase(iterator f, iterator l);
- void clear();
+ void insert(iterator pos, InputIterator f, InputIterator l);
+
+ void erase(iterator pos, size_type n=1);
+ void erase(iterator f, iterator l);
+ void clear();
///@}
protected:
private:
-
+
size_type i_;
size_type size_i_;
Container & container_;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
Parse_UInt8<iterator> sizeParser (data);
Parse_UInt16Vec v (sizeParser, data+1);
-
+
BOOST_CHECK_EQUAL( v[0], 0x1011 );
BOOST_CHECK_EQUAL( v[2], 0x1415 );
BOOST_CHECK_EQUAL( v.size(), 3u );
data[0] = 0x06;
BOOST_CHECK_EQUAL( v.size(), 6u );
BOOST_CHECK_EQUAL( v.bytes(), 12u );
-
+
iterator i (data+1);
Parse_UInt16Vec::iterator j (v.begin());
Parse_UInt16Vec::iterator e (v.end());
typedef Parse_UInt16Vec::wrapper<Container>::t Parse_UInt16VecWrap;
using namespace boost::assign;
-
+
Container data;
- data +=
+ data +=
0x03, // size
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, // data
0x20, 0x21, 0x22, 0x23, 0x24, 0x25;
BOOST_CHECK_EQUAL( w.size(), 3u );
data[0] = 0x06;
BOOST_CHECK_EQUAL( w.size(), 6u );
-
+
{
iterator i (data.begin()+1);
Parse_UInt16VecWrap::iterator j (w.begin());
BOOST_CHECK_EQUAL( w[0], 0x1011 );
BOOST_CHECK_EQUAL( w[1], 0 );
BOOST_CHECK_EQUAL( w[2], 0x1213 );
-
+
w.insert(w.begin()+3, 2u, 0xfffe);
BOOST_CHECK_EQUAL( w.size(), 9u );
BOOST_CHECK_EQUAL( w[2], 0x1213 );
w.erase(w.begin()+3, w.begin()+5);
BOOST_CHECK_EQUAL( w.size(), 7u );
-
+
w.erase(w.begin()+1);
BOOST_CHECK_EQUAL( w.size(), 6u );
// This really belongs into ParserBase.test.cc but it's simpler here
BOOST_AUTO_UNIT_TEST(parserTraits_test)
{
- // Really, this could be checked by BOOST_STATIC_ASSERT since
+ // Really, this could be checked by BOOST_STATIC_ASSERT since
// it's compile-time ...
BOOST_CHECK( Parser_traits< Parse_UInt32<> >::fixed_size );
BOOST_CHECK( (! Parser_traits< Parse_Vector< Parse_UInt16<>,Parse_UInt16<> > >::fixed_size) );
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace senf {
-
+
namespace impl { struct ParserBase; }
- struct nil
- : public boost::iterator_facade<nil,char,boost::random_access_traversal_tag>
+ struct nil
+ : public boost::iterator_facade<nil,char,boost::random_access_traversal_tag>
{
- // Theese are declared to make nil a valid iterator. All
- // access to an instance of this iterator however is invalid
- // (these members are not implemented only declared)
- char & dereference() const;
- bool equal(nil other) const;
- void increment();
- void decrement();
- void advance(int n);
- int distance_to(nil other) const;
+ // Theese are declared to make nil a valid iterator. All
+ // access to an instance of this iterator however is invalid
+ // (these members are not implemented only declared)
+ char & dereference() const;
+ bool equal(nil other) const;
+ void increment();
+ void decrement();
+ void advance(int n);
+ int distance_to(nil other) const;
};
/** \brief Parser framework
To implement a new parser, write a template implementing the
following members:
-
+
\code
template <class Iterator=nil, class IPacket=nil>
struct Parser_Example
Parse_Example() {}
Parse_Example(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
-
+
[static] unsigned bytes()
{
// return the size of the parsed header. This
Parse_Field2 field2() const { return Parse_Field2 (this->i()+2); }
};
\endcode
-
+
Every parser must have some mandatory fixed members which are:
-
+
- struct rebind: This structure allows the parser to be
converted to a parser of the same type but with a different
iterator. Parser may have more than the two standard
parameters must be provided from the outside template
- byte_iterator: A typedef for the Iterator class used
-
+
- Non Iterator constructor: This constructor is only used when
the parser is inherited into a Packet class.
-
+
- Iterator constructor: This constructor must call the
corresponding ParserBase constructor.
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
-
+
// default default constructor
// default copy constructor
// default copy assignment
static void init() {};
private:
-
+
};
template <class Iterator>
static void init() {}
template <class SomePacket>
static void init(typename SomePacket::ptr) {}
-
+
private:
Iterator i_;
};
/** \brief Addtiional Parser information
-
+
Parser_traits provids abstract information about an unknown
parser. Besides the information already available within the
Parser it provides an additional 'fixed_sized' member which is
template <class Parser>
unsigned min_bytes();
-
+
}
///////////////////////////////hh.e////////////////////////////////////////
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class Parser, class Iterator>
bool check(Iterator const & b, Iterator const & e, ParserBase *);
-
+
template <class Parser, class Iterator>
bool check(Iterator const & b, Iterator const & e, void *);
template <class Parser, bool Fixed>
struct ParserCheck {
template <class Iterator>
- static unsigned check(Iterator const & b, Iterator const & e)
+ static unsigned check(Iterator const & b, Iterator const & e)
{ return Parser::check(b,e); }
};
-
+
template <class Parser>
struct ParserCheck<Parser,true> {
template <class Iterator>
static unsigned check(Iterator const & b, Iterator const & e)
{ return unsigned(e-b) >= Parser::bytes(); }
};
-
+
template <class Parser>
unsigned min_bytes(ParserBase *);
-
+
template <class Parser>
unsigned min_bytes(void *);
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class I=senf::nil, class P=senf::nil>
struct rebind { typedef Parse_Test<I,P> parser; };
typedef Iterator byte_iterator;
-
+
Parse_Test() {}
Parse_Test(Iterator const & i) : senf::ParserBase<Iterator,IPacket>(i) {}
-
+
static unsigned bytes() { return 14; }
///////////////////////////////////////////////////////////////////////////
template <class I=senf::nil, class P=senf::nil>
struct rebind { typedef Parse_Test<I,P> parser; };
typedef Iterator byte_iterator;
-
+
Parse_Test2() {}
Parse_Test2(Iterator const & i) : senf::ParserBase<Iterator,IPacket>(i) {}
-
+
unsigned bytes() const { return 14; }
static unsigned check(Iterator a, Iterator b)
{ return true; }
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class I=nil,class P=nil> struct Parse_RTCP_BYE;
template <class I=nil,class P=nil> struct Parse_RTCP_APP;
-
+
template <class Iterator=nil, class IPacket=nil>
struct Parse_RTCP : public ParserBase<Iterator,IPacket>
{
Parse_RTCP() {}
Parse_RTCP(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
typedef Parse_UIntField < 0, 2, Iterator > Parse_Version;
typedef Parse_Flag < 2, Iterator > Parse_P;
typedef Parse_UIntField < 3, 8, Iterator > Parse_Count;
- typedef Parse_UInt8 < Iterator > Parse_PT;
+ typedef Parse_UInt8 < Iterator > Parse_PT;
typedef Parse_UInt16 < Iterator > Parse_Length;
typedef Parse_RTCP_RR < Iterator > Parse_RTCP_RR;
Parse_RTCP_RR rr() { return Parse_RTCP_RR (this->i() ); }
Parse_RTCP_SR sr() { return Parse_RTCP_SR (this->i() ); }
Parse_RTCP_SDES sdes() { return Parse_RTCP_SDES (this->i() ); }
- Parse_RTCP_BYE bye() { return Parse_RTCP_BYE (this->i() ); }
+ Parse_RTCP_BYE bye() { return Parse_RTCP_BYE (this->i() ); }
Parse_RTCP_APP app() { return Parse_RTCP_APP (this->i() ); }
-
+
///////////////////////////////////////////////////////////////////////////
unsigned int bytes() const { return 32 + (4 * length()); }
Parse_RTCP_RB(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UInt32 < Iterator > Parse_32bit;
- typedef Parse_UInt8 < Iterator > Parse_8bit;
- typedef Parse_Array < 3, Parse_UInt8<>, Iterator > Parse_24bit;
+ typedef Parse_UInt8 < Iterator > Parse_8bit;
+ typedef Parse_Array < 3, Parse_UInt8<>, Iterator > Parse_24bit;
Parse_32bit ssrc() const { return Parse_32bit(this->i() ); }
Parse_8bit fragLost() const { return Parse_8bit(this->i()+4 ); }
Parse_32bit ehsnr() const { return Parse_32bit(this->i()+8 ); }
Parse_32bit LSR() const { return Parse_32bit(this->i()+12); }
Parse_32bit DLSR() const { return Parse_32bit(this->i()+16); }
-
+
///////////////////////////////////////////////////////////////////////////
- static unsigned int bytes() { return 20; }
+ static unsigned int bytes() { return 20; }
};
Parse_RTCP_RR() {}
Parse_RTCP_RR(Iterator const & i) : Parse_RTCP<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UInt32 < Iterator > Parse_32bit;
typedef Parse_Vector < Parse_RTCP_RB<>, typename Parse_RTCP<Iterator,IPacket>::Parse_Count, Iterator > Parse_rbVec;
Parse_32bit ssrc() const { return Parse_32bit(this->i()+ 4 ); }
-
+
Parse_32bit ntp_msb() const { return Parse_32bit(this->i()+ 8 ); }
Parse_32bit ntp_lsb() const { return Parse_32bit(this->i()+ 12 ); }
Parse_32bit timestamp() const { return Parse_32bit(this->i()+ 16 ); }
Parse_32bit spcount() const { return Parse_32bit(this->i()+ 20 ); }
Parse_32bit socount() const { return Parse_32bit(this->i()+ 24 ); }
- Parse_rbVec rbVec() const { return Parse_rbVec(this->count(), this->i() + 28 ); }
+ Parse_rbVec rbVec() const { return Parse_rbVec(this->count(), this->i() + 28 ); }
};
Parse_RTCP_SR() {}
Parse_RTCP_SR(Iterator const & i) : Parse_RTCP<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UInt32 < Iterator > Parse_32bit;
typedef Parse_Vector < Parse_RTCP_RB<>, typename Parse_RTCP<Iterator,IPacket>::Parse_Count, Iterator > Parse_rbVec;
Parse_32bit ssrc() const { return Parse_32bit(this->i()+ 4 ); }
Parse_rbVec rbVec() const { return Parse_rbVec(this->count(), this->i() + 8 ); }
-
+
};
template <class Iterator=nil, class IPacket=nil>
Parse_RTCP_item() {}
Parse_RTCP_item(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UInt8 < Iterator > Parse_8bit;
typedef Parse_UInt32 < Iterator > Parse_32bit;
typedef Parse_Vector < Parse_UInt8<>, Parse_UInt8<>, Iterator > Parse_desc;
-
+
Parse_8bit typeField() const { return Parse_8bit(this->i() ); }
- Parse_8bit length() const { return Parse_8bit(this->i()+1 ); }
+ Parse_8bit length() const { return Parse_8bit(this->i()+1 ); }
Parse_desc desc() const { return Parse_desc(this->length(), this->i()+2 ); }
Parse_RTCP_chunk() {}
Parse_RTCP_chunk(Iterator const & i) : Parse_RTCP<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UInt32 < Iterator > Parse_32bit;
typedef Parse_UInt8 < Iterator > Parse_8bit;
typedef Parse_ListS < Parse_RTCP_item<>, Sentinel_EmptyList<Parse_RTCP_item<> >, Iterator, IPacket> Parse_itemList;
-
+
Parse_32bit ssrc() const { return Parse_32bit(this->i() ); }
Parse_itemList itemList() const { return Parse_itemList(this->i() + 4 ); }
-
+
};
Parse_RTCP_SDES() {}
Parse_RTCP_SDES(Iterator const & i) : Parse_RTCP<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_Vector < Parse_RTCP_chunk<>, typename Parse_RTCP<Iterator,IPacket>::Parse_Count, Iterator > Parse_chunkVec;
-
+
Parse_chunkVec chunkVec() const { return Parse_chunkVec(this->count(), this->i()+4 ); }
-
+
};
template <class Iterator, class IPacket>
Parse_RTCP_BYE() {}
Parse_RTCP_BYE(Iterator const & i) : Parse_RTCP<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_Vector < Parse_UInt32<>, typename Parse_RTCP<Iterator,IPacket>::Parse_Count, Iterator > Parse_ssrcVec;
Parse_ssrcVec ssrcVec() const { return Parse_ssrcVec(this->count(), this->i()+4 ); }
Parse_RTCP_APP() {}
Parse_RTCP_APP(Iterator const & i) : Parse_RTCP<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UInt32 < Iterator > Parse_32bit;
- typedef Parse_Vector < Parse_UInt32<>, typename Parse_RTCP<Iterator,IPacket>::Parse_Length, Iterator > Parse_dataVec;
+ typedef Parse_Vector < Parse_UInt32<>, typename Parse_RTCP<Iterator,IPacket>::Parse_Length, Iterator > Parse_dataVec;
Parse_32bit ssrc() const { return Parse_32bit(this->i()+4); }
Parse_32bit name() const { return Parse_32bit(this->i()+8); }
class RTCPPacket
- : public Packet,
+ : public Packet,
public Parse_RTCP<Packet::iterator, RTCPPacket>
{
using Packet::registerInterpreter;
-
+
public:
///////////////////////////////////////////////////////////////////////////
// Types
friend class Packet;
};
-
+
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
{
// RTCP RR (no RB)
- unsigned char data_1[] = {
- 0x80, 0xc8, 0x00, 0x06,
- 0xe5, 0x70, 0xaa, 0x18,
+ unsigned char data_1[] = {
+ 0x80, 0xc8, 0x00, 0x06,
+ 0xe5, 0x70, 0xaa, 0x18,
0xc7, 0xc2, 0xb2, 0x00,
0xc3, 0xd7, 0x0e, 0x96,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x0d, 0xc8
-
- };
+
+ };
typedef unsigned char * iterator_1;
Parse_RTCP<iterator_1> p_1(data_1);
BOOST_CHECK_EQUAL( p_1.version(), 2u );
BOOST_CHECK_EQUAL( p_1.padding(), 0 );
- BOOST_CHECK_EQUAL( p_1.count(), 0u );
+ BOOST_CHECK_EQUAL( p_1.count(), 0u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_1.payloadType()), 200u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_1.length()), 0x0006u );
/// \todo RTCP RR
- unsigned char data_2[] = {
- 0x82, 0xc8, 0x00, 0x06,
- 0xe5, 0x70, 0xaa, 0x18,
+ unsigned char data_2[] = {
+ 0x82, 0xc8, 0x00, 0x06,
+ 0xe5, 0x70, 0xaa, 0x18,
0xc7, 0xc2, 0xb2, 0x00,
0xc3, 0xd7, 0x0e, 0x96,
0x00, 0x00, 0x00, 0x00,
0x09, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0x16,
0x20, 0x21, 0x22, 0x23
-
- };
+
+ };
typedef unsigned char * iterator_2;
Parse_RTCP<iterator_2> p_2(data_2);
BOOST_CHECK_EQUAL( p_2.version(), 2u );
BOOST_CHECK_EQUAL( p_2.padding(), 0 );
- BOOST_CHECK_EQUAL( p_2.count(), 2u );
+ BOOST_CHECK_EQUAL( p_2.count(), 2u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_2.payloadType()), 200u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_2.length()), 0x0006u );
BOOST_CHECK_EQUAL( p_2.rr().rbVec().size(), 0x02u );
-
+
BOOST_CHECK_EQUAL( p_2.rr().rbVec().begin()->ssrc(), 0x01020304u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_2.rr().rbVec().begin()->fragLost()), 0x05u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_2.rr().rbVec().begin()->cnpl()[0]), 0x06u );
// RTCP SR
- unsigned char data_3[] = {
- 0x82, 0xc9, 0x00, 0x06,
- 0xe5, 0x70, 0xaa, 0x18,
-
+ unsigned char data_3[] = {
+ 0x82, 0xc9, 0x00, 0x06,
+ 0xe5, 0x70, 0xaa, 0x18,
+
0x99, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
0x09, 0x10, 0x11, 0x12,
0x09, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0x16,
0x20, 0x21, 0x22, 0x23
-
- };
+
+ };
typedef unsigned char * iterator_3;
Parse_RTCP<iterator_3> p_3(data_3);
BOOST_CHECK_EQUAL( p_3.version(), 2u );
BOOST_CHECK_EQUAL( p_3.padding(), 0 );
- BOOST_CHECK_EQUAL( p_3.count(), 2u );
+ BOOST_CHECK_EQUAL( p_3.count(), 2u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_3.payloadType()), 201u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_3.length()), 0x0006u );
BOOST_CHECK_EQUAL( p_3.sr().ssrc(), 0xe570aa18u );
BOOST_CHECK_EQUAL( p_3.sr().rbVec().size(), 0x02u );
-
+
typedef unsigned char * iterator;
typedef Parse_UIntField < 3, 8, iterator > Parse_Count;
typedef Parse_Vector < Parse_RTCP_RB<>, Parse_Count, iterator > Parse_rbVec;
/// \todo RTCP SDES
- unsigned char data_4[] = {
- 0x81, 0xca, 0x00, 0x04,
- 0xe5, 0x70, 0xaa, 0x18,
- 0x01, 0x09, 0x39, 0x30,
- 0x31, 0x31, 0x33, 0x35,
+ unsigned char data_4[] = {
+ 0x81, 0xca, 0x00, 0x04,
+ 0xe5, 0x70, 0xaa, 0x18,
+ 0x01, 0x09, 0x39, 0x30,
+ 0x31, 0x31, 0x33, 0x35,
0x37, 0x36, 0x37, 0x00
-
- };
+
+ };
typedef unsigned char * iterator_4;
- Parse_RTCP<iterator_4> p_4(data_4);
+ Parse_RTCP<iterator_4> p_4(data_4);
BOOST_CHECK_EQUAL( p_4.version(), 2u );
BOOST_CHECK_EQUAL( p_4.padding(), 0 );
- BOOST_CHECK_EQUAL( p_4.count(), 1u );
+ BOOST_CHECK_EQUAL( p_4.count(), 1u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_4.payloadType()), 202u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_4.length()), 0x0004u );
// BOOST_CHECK( p_4.sdes().chunkList()[0].itemList().check(data_4+20) );
// BOOST_CHECK_EQUAL(p.sdes().chunkList()[0].chunkList().size(), 1);
-//item
+//item
// typeField(), 0x01u
// length(), 0x09u
// desc(), 0x393031313335373637u
#endif
- // RTCP BYE
- unsigned char data_5[] = {
- 0x82, 0xcb, 0x00, 0x06,
-
+ // RTCP BYE
+ unsigned char data_5[] = {
+ 0x82, 0xcb, 0x00, 0x06,
+
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08
-
- };
+
+ };
typedef unsigned char * iterator_5;
Parse_RTCP<iterator_5> p_5(data_5);
BOOST_CHECK_EQUAL( p_5.version(), 2u );
BOOST_CHECK_EQUAL( p_5.padding(), 0 );
- BOOST_CHECK_EQUAL( p_5.count(), 2u );
+ BOOST_CHECK_EQUAL( p_5.count(), 2u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_5.payloadType()), 203u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_5.length()), 0x0006u );
BOOST_CHECK_EQUAL( p_5.bye().ssrcVec()[1], 0x05060708u );
- // RTCP APP
- unsigned char data_6[] = {
- 0x82, 0x7b, 0x00, 0x05,
-
+ // RTCP APP
+ unsigned char data_6[] = {
+ 0x82, 0x7b, 0x00, 0x05,
+
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
0x09, 0x10, 0x11, 0x12,
0x00, 0x00, 0x00, 0x08
-
- };
+
+ };
typedef unsigned char * iterator_6;
Parse_RTCP<iterator_6> p_6(data_6);
BOOST_CHECK_EQUAL( p_6.version(), 2u );
BOOST_CHECK_EQUAL( p_6.padding(), 0 );
- BOOST_CHECK_EQUAL( p_6.count(), 2u );
+ BOOST_CHECK_EQUAL( p_6.count(), 2u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_6.payloadType()), 123u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_6.length()), 0x0005u );
BOOST_CHECK_EQUAL( p_6.app().ssrc(), 0x01020304u );
- BOOST_CHECK_EQUAL( p_6.app().name(), 0x05060708u );
-#if 0
+ BOOST_CHECK_EQUAL( p_6.app().name(), 0x05060708u );
+#if 0
BOOST_CHECK_EQUAL( p_6.app().appData().size(), 2u );
#endif
BOOST_CHECK_EQUAL( p_6.app().appData()[0], 0x09101112u );
}
-
+
BOOST_AUTO_UNIT_TEST(rtcpPacket_packet)
{
#if 0
- unsigned char data_1[] = {
- 0x80, 0xc8, 0x00, 0x06,
- 0xe5, 0x70, 0xaa, 0x18,
+ unsigned char data_1[] = {
+ 0x80, 0xc8, 0x00, 0x06,
+ 0xe5, 0x70, 0xaa, 0x18,
0xc7, 0xc2, 0xb2, 0x00,
0xc3, 0xd7, 0x0e, 0x96,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x0d, 0xc8
-
- };
+
+ };
RTCPPacket::ptr p_1 (Packet::create<RTCPPacket>(data_1, data_1+sizeof(data_1)));
BOOST_CHECK_EQUAL( p_1->version(), 2u );
BOOST_CHECK_EQUAL( p_1->padding(), 0 );
- BOOST_CHECK_EQUAL( p_1->count(), 0u );
+ BOOST_CHECK_EQUAL( p_1->count(), 0u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_1->payloadType()), 200u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(p_1->length()), 0x0006u );
BOOST_CHECK_EQUAL(p_1->rr().spcount(), 0x01u );
BOOST_CHECK_EQUAL(p_1->rr().socount(), 0x0dc8u );
#endif
-
+
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
if(extension()){
Packet::registerInterpreter<RTPUnknownExtensionPacket>(begin()+bytes(),end());
}else{
-
- int paddingOctets = 0;
+
+ int paddingOctets = 0;
if(padding()){
- paddingOctets = paddingOctet();
- }
+ paddingOctets = paddingOctet();
+ }
registerInterpreter(payloadType(),begin()+bytes(),end()-paddingOctets);
}
}
int paddingOctets = 0;
if(get_prev<RTPPacket>()->padding()){
- paddingOctets = get_prev<RTPPacket>()->paddingOctet();
+ paddingOctets = get_prev<RTPPacket>()->paddingOctet();
}
registerInterpreter(get_prev<RTPPacket>()->payloadType(),begin()+p.bytes(),end()-paddingOctets);
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace senf {
-
+
template <class Iterator=nil, class IPacket=nil>
struct Parse_RTP : public ParserBase<Iterator,IPacket>
{
Parse_RTP() {}
Parse_RTP(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
typedef Parse_UIntField < 0, 2, Iterator > Parse_Version;
typedef Parse_UInt16 < Iterator > Parse_Seq;
typedef Parse_UInt32 < Iterator > Parse_32bit;
typedef Parse_Vector < Parse_32bit, Parse_CC, Iterator > Parse_CCVec;
-
+
Parse_Version version() const { return Parse_Version (this->i() ); }
Parse_P padding() const { return Parse_P (this->i() ); }
Parse_X extension() const { return Parse_X (this->i() ); }
Parse_Seq seqNumber() const { return Parse_Seq (this->i() + 2 ); }
Parse_32bit timestamp() const { return Parse_32bit (this->i() + 4 ); }
Parse_32bit ssrc() const { return Parse_32bit (this->i() + 8 ); }
- Parse_CCVec csrcList() const { return Parse_CCVec (csrcCount(), this->i() + 12 ); }
+ Parse_CCVec csrcList() const { return Parse_CCVec (csrcCount(), this->i() + 12 ); }
+
+
-
-
///////////////////////////////////////////////////////////////////////////
unsigned int bytes() const { return 12 + ( 4 * csrcCount()); }
static bool check(Iterator const & b, Iterator const & e)
{ return e-b>= 12 and unsigned(e-b) >= Parse_RTP<Iterator>(b).bytes(); }
-
+
};
struct RTPTypes {
};
class RTPPacket
- : public Packet,
- public Parse_RTP<Packet::iterator, RTPPacket>,
+ : public Packet,
+ public Parse_RTP<Packet::iterator, RTPPacket>,
public PacketRegistryMixin<RTPTypes,RTPPacket>
{
using Packet::registerInterpreter;
///////////////////////////////////////////////////////////////////////////
typedef Parse_UInt8 < Packet::iterator > Parse_paddingOctet;
-
- Parse_paddingOctet paddingOctet() const {
- return Parse_paddingOctet( end() -1 );
- }
+
+ Parse_paddingOctet paddingOctet() const {
+ return Parse_paddingOctet( end() -1 );
+ }
private:
template <class Arg>
friend class Packet;
};
-
-
+
+
template <class Iterator=nil, class IPacket=nil>
struct Parse_RTPExtensionBase : public ParserBase<Iterator,IPacket>
{
Parse_RTPExtensionBase(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UInt16 < Iterator > Parse_16bit;
Parse_16bit proDef() const { return Parse_16bit(this->i()); };
Parse_16bit length() const { return Parse_16bit(this->i()+2); };
- unsigned int bytes() const { return 4 + length(); }
+ unsigned int bytes() const { return 4 + length(); }
static bool check(Iterator const & b, Iterator const & e)
{ return e-b>=4 && unsigned(e-b) >= Parse_RTPExtensionBase<Iterator>(b).bytes(); }
- };
+ };
- class RTPExtensionBasePacket
+ class RTPExtensionBasePacket
: public Packet,
public PacketRegistryMixin<RTPTypes, RTPExtensionBasePacket>
{
using PacketRegistryMixin<RTPTypes,RTPExtensionBasePacket>::registerInterpreter;
using Packet::registerInterpreter;
public:
- ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
typedef ptr_t<RTPExtensionBasePacket>::ptr ptr;
protected:
Parse_RTPUnknownExtension() {}
Parse_RTPUnknownExtension(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
-
+
///////////////////////////////////////////////////////////////////////////
-
+
typedef Parse_UInt16 < Iterator > Parse_16bit;
typedef Parse_UInt8 < Iterator > Parse_8bit;
typedef Parse_Vector < Parse_8bit, Parse_16bit, Iterator > Parse_ext;
-
+
Parse_ext ext() const { return Parse_ext (this->length(), this->i() + 4 ); }
};
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
BOOST_AUTO_UNIT_TEST(rtpPacket_parser)
{
- unsigned char data[] = { 0x13, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
+ unsigned char data[] = { 0x13, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
0x09, 0x0A, 0x0B, 0x0C,
0x11, 0x12, 0x13, 0x14, // CSRC 1
0x15, 0x16, 0x17, 0x18, // CSRC 2
- 0x19, 0x1A, 0x1B, 0x1C // CSRC 3
-
- };
+ 0x19, 0x1A, 0x1B, 0x1C // CSRC 3
+
+ };
typedef unsigned char * iterator;
Parse_RTP<iterator> p(data);
BOOST_CHECK_EQUAL( p.version(), 0x00u );
BOOST_CHECK_EQUAL( p.padding(), 0 );
BOOST_CHECK_EQUAL( p.extension(), 1 );
- BOOST_CHECK_EQUAL( p.csrcCount(), 0x03u );
+ BOOST_CHECK_EQUAL( p.csrcCount(), 0x03u );
BOOST_CHECK_EQUAL( p.marker(), 0 );
BOOST_CHECK_EQUAL( p.payloadType(), 0x02u );
// the static_cast is to silence gcc-3.3
BOOST_CHECK_EQUAL( static_cast<unsigned>(p.seqNumber()), 0x0304u );
BOOST_CHECK_EQUAL( p.timestamp(), 0x05060708u );
BOOST_CHECK_EQUAL( p.ssrc(), 0x090A0B0Cu );
-
- BOOST_CHECK_EQUAL( p.csrcList()[0], 0x11121314u );
+
+ BOOST_CHECK_EQUAL( p.csrcList()[0], 0x11121314u );
BOOST_CHECK_EQUAL( p.csrcList()[1], 0x15161718u );
BOOST_CHECK_EQUAL( p.csrcList()[2], 0x191A1B1Cu );
}
-
+
BOOST_AUTO_UNIT_TEST(rtpPacket_packet)
{
- unsigned char data[] = { 0x33, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
+ unsigned char data[] = { 0x33, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
0x09, 0x0A, 0x0B, 0x0C,
0x11, 0x12, 0x13, 0x14, // CSRC 1
0x15, 0x16, 0x17, 0x18, // CSRC 2
- 0x19, 0x1A, 0x1B, 0x1C, // CSRC 3
-
+ 0x19, 0x1A, 0x1B, 0x1C, // CSRC 3
+
0x20, 0x21, 0x00, 0x04, // ex
0x24, 0x25, 0x26, 0x27, // ex
-
+
0x20, 0x21, 0x08, 0x23, // paylaod
0x20, 0x00, 0x00, 0x03 // payload
-
- };
+
+ };
RTPPacket::ptr p (Packet::create<RTPPacket>(data, data+sizeof(data)));
BOOST_CHECK_EQUAL( p->version(), 0x00u );
BOOST_CHECK_EQUAL( p->padding(), 1 );
BOOST_CHECK_EQUAL( p->extension(), 1 );
- BOOST_CHECK_EQUAL( p->csrcCount(), 0x03u );
+ BOOST_CHECK_EQUAL( p->csrcCount(), 0x03u );
BOOST_CHECK_EQUAL( p->marker(), 0 );
BOOST_CHECK_EQUAL( p->payloadType(), 0x02u );
// the static_cast is to silence gcc-3.3
BOOST_CHECK_EQUAL( p->paddingOctet(), 3 );
- BOOST_CHECK_EQUAL( p->csrcList()[0], 0x11121314u );
+ BOOST_CHECK_EQUAL( p->csrcList()[0], 0x11121314u );
BOOST_CHECK_EQUAL( p->csrcList()[1], 0x15161718u );
BOOST_CHECK_EQUAL( p->csrcList()[2], 0x191A1B1Cu );
-
+
BOOST_REQUIRE( p->next() );
BOOST_CHECK( p->next()->is<RTPUnknownExtensionPacket>() );
BOOST_CHECK_EQUAL( static_cast<unsigned>(v->length()), 0x04u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(v->ext()[0]), 0x24u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(v->ext()[2]), 0x26u );
-
+
BOOST_REQUIRE( v->next() );
DataPacket::ptr d (v->next()->as<DataPacket>());
-
+
BOOST_CHECK_EQUAL( d->size(), 5u );
-
+
}
BOOST_AUTO_UNIT_TEST(eth_rtpPacket_packet)
{
- unsigned char data[] = {
+ unsigned char data[] = {
// Ethernet
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // destination MAC
0x08, 0x00, // EtherType: IPv4 0x08
// IPv4
- 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x11, 0x0B, 0x0C, // EtherType: UDP 0x11
- 0x11, 0x12, 0x13, 0x14,
- 0x15, 0x16, 0x17, 0x18,
+ 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x11, 0x0B, 0x0C, // EtherType: UDP 0x11
+ 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18,
- // UDP
+ // UDP
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
// RTP
- 0x33, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
+ 0x33, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
0x09, 0x0A, 0x0B, 0x0C,
0x11, 0x12, 0x13, 0x14, // CSRC 1
0x15, 0x16, 0x17, 0x18, // CSRC 2
- 0x19, 0x1A, 0x1B, 0x1C, // CSRC 3
-
+ 0x19, 0x1A, 0x1B, 0x1C, // CSRC 3
+
0x20, 0x21, 0x00, 0x04, // ex
0x24, 0x25, 0x26, 0x27, // ex
-
+
0x20, 0x21, 0x08, 0x23, // paylaod
0x20, 0x00, 0x00, 0x03 // payload
-
- };
+
+ };
// Ethernet
EthernetPacket::ptr p (Packet::create<EthernetPacket>(data, data+sizeof(data)));
BOOST_CHECK_EQUAL( udp->source(), 0x0102 );
BOOST_CHECK_EQUAL( udp->destination(), 0x0304 );
BOOST_CHECK_EQUAL( udp->length(), 0x0506 );
- BOOST_CHECK_EQUAL( udp->crc(), 0x0708 );
+ BOOST_CHECK_EQUAL( udp->crc(), 0x0708 );
// RTP
BOOST_CHECK_EQUAL( rtp->version(), 0x00u );
BOOST_CHECK_EQUAL( rtp->padding(), 1 );
BOOST_CHECK_EQUAL( rtp->extension(), 1 );
- BOOST_CHECK_EQUAL( rtp->csrcCount(), 0x03u );
+ BOOST_CHECK_EQUAL( rtp->csrcCount(), 0x03u );
BOOST_CHECK_EQUAL( rtp->marker(), 0 );
BOOST_CHECK_EQUAL( rtp->payloadType(), 0x02u );
// the static_cast is to silence gcc-3.3
BOOST_CHECK_EQUAL( rtp->paddingOctet(), 3 );
- BOOST_CHECK_EQUAL( rtp->csrcList()[0], 0x11121314u );
+ BOOST_CHECK_EQUAL( rtp->csrcList()[0], 0x11121314u );
BOOST_CHECK_EQUAL( rtp->csrcList()[1], 0x15161718u );
BOOST_CHECK_EQUAL( rtp->csrcList()[2], 0x191A1B1Cu );
-
+
BOOST_REQUIRE( rtp->next() );
BOOST_CHECK( rtp->next()->is<RTPUnknownExtensionPacket>() );
BOOST_CHECK_EQUAL( static_cast<unsigned>(ex->length()), 0x04u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(ex->ext()[0]), 0x24u );
BOOST_CHECK_EQUAL( static_cast<unsigned>(ex->ext()[2]), 0x26u );
-
+
BOOST_REQUIRE( ex->next() );
DataPacket::ptr pay (ex->next()->as<DataPacket>());
-
+
BOOST_CHECK_EQUAL( pay->size(), 5u );
-
+
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacket>
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacket>
registerUDPPacket (17);
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
-
+
// See RFC768
template <class Iterator=nil, class IPacket=nil>
struct Parse_UDP : public ParserBase<Iterator,IPacket>
///////////////////////////////////////////////////////////////////////////
- typedef Parse_UInt16 < Iterator > Parse_16bit;
-
+ typedef Parse_UInt16 < Iterator > Parse_16bit;
+
Parse_16bit source() const { return Parse_16bit (this->i() ); }
Parse_16bit destination() const { return Parse_16bit (this->i() + 2 ); }
Parse_16bit length() const { return Parse_16bit (this->i() + 4 ); }
};
class UDPPacket
- : public Packet,
+ : public Packet,
public Parse_UDP<Packet::iterator, UDPPacket>
{
public:
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
{
unsigned char data[] = { 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08
- };
+ };
typedef unsigned char * iterator;
Parse_UDP<iterator> p(data);
BOOST_CHECK_EQUAL( p.source(), 0x0102 );
BOOST_CHECK_EQUAL( p.destination(), 0x0304 );
BOOST_CHECK_EQUAL( p.length(), 0x0506 );
- BOOST_CHECK_EQUAL( p.crc(), 0x0708 );
-
+ BOOST_CHECK_EQUAL( p.crc(), 0x0708 );
+
}
-
+
BOOST_AUTO_UNIT_TEST(udpPacket_packet)
{
unsigned char data[] = { 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08
- };
+ };
UDPPacket::ptr p (Packet::create<UDPPacket>(data, data+sizeof(data)));
BOOST_CHECK_EQUAL( p->source(), 0x0102 );
BOOST_CHECK_EQUAL( p->destination(), 0x0304 );
BOOST_CHECK_EQUAL( p->length(), 0x0506 );
- BOOST_CHECK_EQUAL( p->crc(), 0x0708 );
+ BOOST_CHECK_EQUAL( p->crc(), 0x0708 );
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class Derived, class Value, class Traversal, class Reference> struct iterator_facade {};
template <class T> struct intrusive_ptr { T * ptr; };
template <class T> struct shared_ptr { T * ptr; };
-
+
}
namespace std {
struct exception {};
template <class T> struct vector { T * elements; };
template <class T> struct list { T * elements; };
-
+
}
///////////////////////////////hh.e////////////////////////////////////////
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cci.p///////////////////////////////////////
prefix_ senf::TypeIdValue::TypeIdValue()
- : value_(new ValueImpl<void>())
+ : value_(new ValueImpl<void>())
{}
prefix_ senf::TypeIdValue::TypeIdValue(TypeIdValue const & other)
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class Type>
prefix_ senf::TypeIdValue::TypeIdValue(Type *)
- : value_(new ValueImpl<Type>())
+ : value_(new ValueImpl<Type>())
{}
template <class Type>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
};
TypeIdValue const typeIdValue();
-
+
template <class Type>
TypeIdValue const typeIdValue();
-
+
}
///////////////////////////////hh.e////////////////////////////////////////
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
SENFSCons.StandardTargets(env)
SENFSCons.GlobalTargets(env)
SENFSCons.Doxygen(env)
-SENFSCons.DoxyXRef(env,
+SENFSCons.DoxyXRef(env,
HTML_HEADER = '#/doclib/doxy-header-overview.html',
HTML_FOOTER = '#/doclib/doxy-footer.html')
\c poll. The Scheduler library is based on the highly efficient
(but linux specific) \c epoll() system call.
- The library provides
- \li a central \ref Scheduler singleton and
+ The library provides
+ \li a central \ref Scheduler singleton and
\li \ref ReadHelper and \ref WriteHelper templates to simplify
- common tasks.
+ common tasks.
In it's current incarnation, the library only supports network
file handles (including pipes etc) and simple timers (especially
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// mode: flyspell
// mode: auto-fill
-// ispell-local-dictionary: "american"
// End:
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Copyright (C) 2006
+// Copyright (C) 2006
/** \file
\brief ReadHelper inline non-template implementation */
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Copyright (C) 2006
+// Copyright (C) 2006
/** \file
\brief ReadHelper non-inline template implementation */
template <class Handle>
prefix_ senf::ReadHelper<Handle>::ReadHelper(Handle handle, std::string::size_type maxSize,
InternalPredicate * predicate, Callback cb)
- : handle_(handle), maxSize_(maxSize), predicate_(predicate), callback_(cb),
+ : handle_(handle), maxSize_(maxSize), predicate_(predicate), callback_(cb),
errno_(0), complete_(false)
{
// Here we add a *static* member taking a *smart* pointer as first
// scheduler. This ensures, that the refcount is at least 1 as
// long as the helper is registered with the scheduler.
senf::Scheduler::instance()
- .add(handle,boost::bind(&ReadHelper::dispatchProcess,ptr(this),_1,_2),
- senf::Scheduler::EV_READ);
+ .add(handle,boost::bind(&ReadHelper::dispatchProcess,ptr(this),_1,_2),
+ senf::Scheduler::EV_READ);
}
template <class Handle>
{
ptr guard (this); // To ensure, 'this' is deleted only after this method terminates ...
senf::Scheduler::instance()
- .remove(handle_,senf::Scheduler::EV_READ);
+ .remove(handle_,senf::Scheduler::EV_READ);
}
template <class Handle>
{
/** \fixme Move the done() calls to outside the try/catch block */
try {
- if (event != senf::Scheduler::EV_READ)
- throw SystemException(EPIPE);
- std::string rcv (handle.read(maxSize_ - data_.size()));
- data_.append(rcv);
- std::string::size_type n = predicate_ ? (*predicate_)(data_) : std::string::npos;
- if (n != std::string::npos || data_.size() >= maxSize_ || rcv.size() == 0) {
- complete_ = true;
- if (n < data_.size()) {
- tail_.assign(data_,n,std::string::npos);
- data_.erase(n);
- }
- done();
- }
+ if (event != senf::Scheduler::EV_READ)
+ throw SystemException(EPIPE);
+ std::string rcv (handle.read(maxSize_ - data_.size()));
+ data_.append(rcv);
+ std::string::size_type n = predicate_ ? (*predicate_)(data_) : std::string::npos;
+ if (n != std::string::npos || data_.size() >= maxSize_ || rcv.size() == 0) {
+ complete_ = true;
+ if (n < data_.size()) {
+ tail_.assign(data_,n,std::string::npos);
+ data_.erase(n);
+ }
+ done();
+ }
}
catch (senf::SystemException const & ex) {
- errno_ = ex.err;
- done();
+ errno_ = ex.err;
+ done();
}
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Copyright (C) 2006
+// Copyright (C) 2006
/** \file
\brief ReadHelper inline template implementation */
senf::ReadHelper<Handle>::dispatch(Handle handle, std::string::size_type maxSize,
Predicate const & predicate, Callback callback)
{
- return ptr(new ReadHelper(handle, maxSize,
- new typename InternalPredicate::template Dispatcher<Predicate>(predicate),
- callback));
+ return ptr(new ReadHelper(handle, maxSize,
+ new typename InternalPredicate::template Dispatcher<Predicate>(predicate),
+ callback));
}
template <class Handle>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Copyright (C) 2006
+// Copyright (C) 2006
/** \file
\brief ReadHelper public header */
namespace senf {
- /** \brief Asyncronous reading helper
+ /** \brief Asyncronous reading helper
- This class provides a simple asynchronous reading facility. This helper will register with
- the Scheduler and read incoming data. It will collect the data until a specific numbner of
- bytes has been read or some Predicate evaluated on the data read thus far signals end of
- data.
+ This class provides a simple asynchronous reading facility. This helper will register with
+ the Scheduler and read incoming data. It will collect the data until a specific numbner of
+ bytes has been read or some Predicate evaluated on the data read thus far signals end of
+ data.
- The ReadHelper accepts the same flexible file handle interfaces as the Scheduler.
-
- The callback must take a ReadHelper::ptr argument. Using this ReadHelper instance, the
- callback can access the data read or retrieve state information.
+ The ReadHelper accepts the same flexible file handle interfaces as the Scheduler.
- The ReadHelper separates the data into two parts: data() will return the matched data,
- tail() will return any surplus data already read. If you don't specify a predicate, tail()
- will always be empty (there may however some data be left in the socket input buffer after
- the ReadHelper returns).
+ The callback must take a ReadHelper::ptr argument. Using this ReadHelper instance, the
+ callback can access the data read or retrieve state information.
- The predicate is any class instance with an <tt>operator(std::string const &)</tt>. This
- operator is called, whenever some data has been read. If the data is not yet complete, the
- predicate must return \c std::string::npos. If the ReadHelper should stop readeing more
- data, the predicate must return the number of bytes which are to be considered 'matched'.
+ The ReadHelper separates the data into two parts: data() will return the matched data,
+ tail() will return any surplus data already read. If you don't specify a predicate, tail()
+ will always be empty (there may however some data be left in the socket input buffer after
+ the ReadHelper returns).
- \todo Move all not Handle dependent members to a ReadHandleBase class
- \todo Add an optional <tt>std::string const & tail</tt> argument to the constructors which
- takes the tail() of a previous ReadHelper instance.
+ The predicate is any class instance with an <tt>operator(std::string const &)</tt>. This
+ operator is called, whenever some data has been read. If the data is not yet complete, the
+ predicate must return \c std::string::npos. If the ReadHelper should stop readeing more
+ data, the predicate must return the number of bytes which are to be considered 'matched'.
+
+ \todo Move all not Handle dependent members to a ReadHandleBase class
+ \todo Add an optional <tt>std::string const & tail</tt> argument to the constructors which
+ takes the tail() of a previous ReadHelper instance.
*/
template <class Handle>
class ReadHelper
- : public senf::intrusive_refcount
+ : public senf::intrusive_refcount
{
public:
///////////////////////////////////////////////////////////////////////////
// Types
-
- typedef boost::intrusive_ptr<ReadHelper> ptr; ///< Smart pointer type for this class
- typedef boost::function<void (ptr)> Callback; ///< Callback type
+
+ typedef boost::intrusive_ptr<ReadHelper> ptr; ///< Smart pointer type for this class
+ typedef boost::function<void (ptr)> Callback; ///< Callback type
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
- static ptr dispatch(Handle handle, std::string::size_type maxSize,
- Callback callback); ///< Register new ReadHandler instance
+ static ptr dispatch(Handle handle, std::string::size_type maxSize,
+ Callback callback); ///< Register new ReadHandler instance
/**< The registered Callback will be called after \a maxSize
- bytes have been read or EOF or some error is
- encountered.
- \post The returned ReadHelper instance is registered
- with the Scheduler to handle read events.
- \param[in] handle file descriptor or handle providing
- the Handle interface defined above.
- \param[in] maxSize maximum number of bytes to read
- \param[in] cb callback
- \returns Smart pointer to new ReadHelper instance */
-
- template <class Predicate>
- static ptr dispatch(Handle handle, std::string::size_type maxSize, Predicate const & predicate,
- Callback callback); ///< Register new ReadHelper instance
+ bytes have been read or EOF or some error is
+ encountered.
+ \post The returned ReadHelper instance is registered
+ with the Scheduler to handle read events.
+ \param[in] handle file descriptor or handle providing
+ the Handle interface defined above.
+ \param[in] maxSize maximum number of bytes to read
+ \param[in] cb callback
+ \returns Smart pointer to new ReadHelper instance */
+
+ template <class Predicate>
+ static ptr dispatch(Handle handle, std::string::size_type maxSize, Predicate const & predicate,
+ Callback callback); ///< Register new ReadHelper instance
/**< The registered Callback will be called after the \a
- predicate returns a Value other than \c
- std::string::npos, \a maxSize bytes have been read, or
- EOF or some error condition is encountered.
- \post The returned ReadHelper instance is registered
- with the Scheduler to handle read events
-. \param[in] handle file descriptor or handle providing
- the Handle interface defined above.
- \param[in] maxSize maximum number of bytes to read
- \param[in] predicate predicate to check
- \param[in] cb callback
- \returns smart pointer to new ReadHelper instance */
+ predicate returns a Value other than \c
+ std::string::npos, \a maxSize bytes have been read, or
+ EOF or some error condition is encountered.
+ \post The returned ReadHelper instance is registered
+ with the Scheduler to handle read events
+. \param[in] handle file descriptor or handle providing
+ the Handle interface defined above.
+ \param[in] maxSize maximum number of bytes to read
+ \param[in] predicate predicate to check
+ \param[in] cb callback
+ \returns smart pointer to new ReadHelper instance */
///@}
///////////////////////////////////////////////////////////////////////////
- Handle handle() const; ///< Access the handle object
- unsigned maxSize() const; ///< Return maximum number of bytes to be read
+ Handle handle() const; ///< Access the handle object
+ unsigned maxSize() const; ///< Return maximum number of bytes to be read
- std::string const & data() const; ///< return data read
- std::string const & tail() const; ///< return data read but not matched by the predicate
+ std::string const & data() const; ///< return data read
+ std::string const & tail() const; ///< return data read but not matched by the predicate
- bool complete() const; ///< Check wether the read has completed successfully
- bool error() const; ///< Check for error condition
- void throw_error() const; ///< If an error occured, throw it
+ bool complete() const; ///< Check wether the read has completed successfully
+ bool error() const; ///< Check for error condition
+ void throw_error() const; ///< If an error occured, throw it
- void revoke(); ///< Remove the ReadHelper from the scheduler
+ void revoke(); ///< Remove the ReadHelper from the scheduler
protected:
private:
- struct InternalPredicate;
+ struct InternalPredicate;
ReadHelper(Handle handle, unsigned maxSize, InternalPredicate * predicate, Callback cb);
- static void dispatchProcess(ptr helper, Handle handle, senf::Scheduler::EventId event);
- void process(Handle handle, senf::Scheduler::EventId event);
- void done();
+ static void dispatchProcess(ptr helper, Handle handle, senf::Scheduler::EventId event);
+ void process(Handle handle, senf::Scheduler::EventId event);
+ void done();
- Handle handle_;
- std::string::size_type maxSize_;
- boost::scoped_ptr<InternalPredicate> predicate_;
- Callback callback_;
+ Handle handle_;
+ std::string::size_type maxSize_;
+ boost::scoped_ptr<InternalPredicate> predicate_;
+ Callback callback_;
- std::string data_;
- std::string tail_;
- int errno_;
- bool complete_;
+ std::string data_;
+ std::string tail_;
+ int errno_;
+ bool complete_;
};
/** \brief ReadHelper predicate matching an arbitrary string
-
- This predicate will terminate the read when the data read matches a given fixed string. All
- data up to and including the string matched is considered to be part of the data() portion,
- everything after the matched string is placed into the tail().
- \see ReadHelper
+ This predicate will terminate the read when the data read matches a given fixed string. All
+ data up to and including the string matched is considered to be part of the data() portion,
+ everything after the matched string is placed into the tail().
+
+ \see ReadHelper
*/
struct ReadUntil
{
ReadUntil(std::string const & target);
- std::string::size_type operator()(std::string const & data);
- std::string target;
+ std::string::size_type operator()(std::string const & data);
+ std::string target;
};
}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Copyright (C) 2006
+// Copyright (C) 2006
/** \file
\brief ReadHelper internal header */
/** \brief Abstract predicate interface
- \internal
+ \internal
*/
template <class Handle>
struct ReadHelper<Handle>::InternalPredicate
{
- virtual ~InternalPredicate() {}
+ virtual ~InternalPredicate() {}
- /** \brief template to runtime polymorphic barrier for the predicate interface
- \internal
+ /** \brief template to runtime polymorphic barrier for the predicate interface
+ \internal
- \implementation This class will provide a polymorphic
- wrapper around the non-polymorphic ReadHelper
- predicate. This is used, so the predicate can be
- specified as an arbitrary callable object (even a
- boost::function or a Boost.Lambda expression) without
- imposing any inheritance relationship on the predicate
- */
- template <class Predicate>
- struct Dispatcher
- : public ReadHelper<Handle>::InternalPredicate
- {
- Dispatcher(Predicate p) : predicate(p) {}
- virtual std::string::size_type operator()(std::string const & data);
- Predicate predicate;
- };
+ \implementation This class will provide a polymorphic
+ wrapper around the non-polymorphic ReadHelper
+ predicate. This is used, so the predicate can be
+ specified as an arbitrary callable object (even a
+ boost::function or a Boost.Lambda expression) without
+ imposing any inheritance relationship on the predicate
+ */
+ template <class Predicate>
+ struct Dispatcher
+ : public ReadHelper<Handle>::InternalPredicate
+ {
+ Dispatcher(Predicate p) : predicate(p) {}
+ virtual std::string::size_type operator()(std::string const & data);
+ Predicate predicate;
+ };
- virtual std::string::size_type operator()(std::string const & data) = 0;
+ virtual std::string::size_type operator()(std::string const & data) = 0;
};
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Unit tests
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\brief Scheduler non-inline non-template implementation
\idea Implement signal handling (See source for more discussion
- about this)
+ about this)
\idea Multithreading support: To support multithreading, the
static member Scheduler::instance() must return a thread-local
// // call epoll
// // block all relevant signals again
// }
-//
+//
// // now handle the event
//
// The signal handler is then simply defined as
memset(&ev,0,sizeof(ev));
ev.events = i->second.epollMask();
ev.data.fd = fd;
-
+
if (epoll_ctl(epollFd_, action, fd, &ev)<0)
throw SystemException(errno);
}
prefix_ void senf::Scheduler::do_remove(int fd, int eventMask)
{
FdTable::iterator i (fdTable_.find(fd));
- if (i == fdTable_.end())
+ if (i == fdTable_.end())
return;
if (eventMask & EV_READ) i->second.cb_read = 0;
memset(&ev,0,sizeof(ev));
ev.events = i->second.epollMask();
ev.data.fd = fd;
-
+
int action (EPOLL_CTL_MOD);
if (ev.events==0) {
action = EPOLL_CTL_DEL;
terminate_ = false;
while (! terminate_) {
- MicroTime timeNow = now();
- while ( ! timerQueue_.empty() && timerQueue_.top().timeout <= timeNow ) {
- timerQueue_.top().cb();
- timerQueue_.pop();
- }
- if (terminate_)
- return;
- int timeout = timerQueue_.empty() ? -1 : int((timerQueue_.top().timeout - timeNow)/1000);
-
+ MicroTime timeNow = now();
+ while ( ! timerQueue_.empty() && timerQueue_.top().timeout <= timeNow ) {
+ timerQueue_.top().cb();
+ timerQueue_.pop();
+ }
+ if (terminate_)
+ return;
+ int timeout = timerQueue_.empty() ? -1 : int((timerQueue_.top().timeout - timeNow)/1000);
+
struct epoll_event ev;
int events = epoll_wait(epollFd_, &ev, 1, timeout);
if (events<0)
// Hmm ... man epoll says, it will NOT return with EINTR ??
throw SystemException(errno);
if (events==0)
- // Timeout .. it will be run when reachiung the top of the loop
+ // Timeout .. it will be run when reachiung the top of the loop
continue;
-
+
FdTable::iterator i = fdTable_.find(ev.data.fd);
BOOST_ASSERT (i != fdTable_.end() );
- EventSpec const & spec (i->second);
+ EventSpec const & spec (i->second);
if (ev.events & EPOLLIN) {
- BOOST_ASSERT(spec.cb_read);
+ BOOST_ASSERT(spec.cb_read);
spec.cb_read(EV_READ);
}
else if (ev.events & EPOLLPRI) {
}
else if (ev.events & EPOLLHUP) {
- if (spec.cb_hup)
- spec.cb_hup(EV_HUP);
- else if (ev.events & EPOLLERR) {
- /** \fixme This is stupid, if cb_write and cb_read are
- the same. The same below. We really have to
- exactly define sane semantics of what to do on
- EPOLLHUP and EPOLLERR. */
- if (spec.cb_write) spec.cb_write(EV_HUP);
- if (spec.cb_read) spec.cb_read(EV_HUP);
- }
+ if (spec.cb_hup)
+ spec.cb_hup(EV_HUP);
+ else if (ev.events & EPOLLERR) {
+ /** \fixme This is stupid, if cb_write and cb_read are
+ the same. The same below. We really have to
+ exactly define sane semantics of what to do on
+ EPOLLHUP and EPOLLERR. */
+ if (spec.cb_write) spec.cb_write(EV_HUP);
+ if (spec.cb_read) spec.cb_read(EV_HUP);
+ }
}
else if (ev.events & EPOLLERR && ! ev.events & EPOLLHUP) {
- if (spec.cb_err)
- spec.cb_err(EV_ERR);
- else {
- if (spec.cb_write) spec.cb_write(EV_ERR);
- if (spec.cb_read) spec.cb_read(EV_ERR);
- }
+ if (spec.cb_err)
+ spec.cb_err(EV_ERR);
+ else {
+ if (spec.cb_write) spec.cb_write(EV_ERR);
+ if (spec.cb_read) spec.cb_read(EV_ERR);
+ }
}
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
input, output or error. This functions are specified using boost::function objects (See <a
href="http://www.boost.org/doc/html/function.html">Boost.Function</a>)
- The Scheduler is based on a generic handle representation. The only information needed from
- a handle, is the intrinsic file descriptor. Any object for which the statement
- \code
- int fd = retrieve_filehandle(object);
- \endcode
- is valid and places the relevent file descriptor into fd can be used as a Handle type. There
- is an implementation of retrieve_filehandle(int) within the library to handle explicit file
- descrptors. The <a href="../../../Socket/doc/html/index.html">Socket library</a> provides an
- implementation of <tt>retrive_filehandle(FileHandle handle)</tt>. If you want to support
- some other handle type, just define an apropriate \c retrieve_filehandle function <em>in
- that types namespace</em>.
-
- It is important to note, that for every combination of file descriptor and event, only a \e
- single handler may be installed. Installing more handlers does not make sense. If you need
- to distribute data to serveral interested parties, you must take care of this yourself.
-
- \todo Fix EventId parameter (probably to int) to allow |-ing without casting ...
+ The Scheduler is based on a generic handle representation. The only information needed from
+ a handle, is the intrinsic file descriptor. Any object for which the statement
+ \code
+ int fd = retrieve_filehandle(object);
+ \endcode
+ is valid and places the relevent file descriptor into fd can be used as a Handle type. There
+ is an implementation of retrieve_filehandle(int) within the library to handle explicit file
+ descrptors. The <a href="../../../Socket/doc/html/index.html">Socket library</a> provides an
+ implementation of <tt>retrive_filehandle(FileHandle handle)</tt>. If you want to support
+ some other handle type, just define an apropriate \c retrieve_filehandle function <em>in
+ that types namespace</em>.
+
+ It is important to note, that for every combination of file descriptor and event, only a \e
+ single handler may be installed. Installing more handlers does not make sense. If you need
+ to distribute data to serveral interested parties, you must take care of this yourself.
+
+ \todo Fix EventId parameter (probably to int) to allow |-ing without casting ...
*/
class Scheduler
: boost::noncopyable
///////////////////////////////////////////////////////////////////////////
// Types
- /// \brief Types of file descriptor events */
- enum EventId { EV_NONE=0,
- EV_READ=1, EV_PRIO=2, EV_WRITE=4, EV_HUP=8, EV_ERR=16,
+ /// \brief Types of file descriptor events */
+ enum EventId { EV_NONE=0,
+ EV_READ=1, EV_PRIO=2, EV_WRITE=4, EV_HUP=8, EV_ERR=16,
EV_ALL=31 };
- /** \brief Template typedef for Callback type
-
- This is a template typedef (which does not exist in C++) that is, a template class whose
- sole member is a typedef symbol defining the callback type given the handle type.
+ /** \brief Template typedef for Callback type
- The Callback is any callable object taking a \c Handle and an \c EventId as argument.
- */
+ This is a template typedef (which does not exist in C++) that is, a template class whose
+ sole member is a typedef symbol defining the callback type given the handle type.
+
+ The Callback is any callable object taking a \c Handle and an \c EventId as argument.
+ */
template <class Handle>
struct GenericCallback {
typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
EventId) > Callback;
};
- /** \brief Callback type for timer events */
- typedef boost::function<void ()> TimerCallback;
+ /** \brief Callback type for timer events */
+ typedef boost::function<void ()> TimerCallback;
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
// default destructor
// no conversion constructors
- /** \brief Return Scheduler instance
-
- This static member is used to access the singleton instance. This member is save to
- return a correctly initialized Scheduler instance even if called at global construction
- time
-
- \implementation This static member just defines the Scheduler as a static method
- variable. The C++ standard then provides above guaratee. The instance will be
- initialized the first time, the code flow passes the variable declaration found in
- the instance() body.
- */
+ /** \brief Return Scheduler instance
+
+ This static member is used to access the singleton instance. This member is save to
+ return a correctly initialized Scheduler instance even if called at global construction
+ time
+
+ \implementation This static member just defines the Scheduler as a static method
+ variable. The C++ standard then provides above guaratee. The instance will be
+ initialized the first time, the code flow passes the variable declaration found in
+ the instance() body.
+ */
static Scheduler & instance();
///@}
///////////////////////////////////////////////////////////////////////////
template <class Handle>
- void add(Handle const & handle,
+ void add(Handle const & handle,
typename GenericCallback<Handle>::Callback const & cb,
int eventMask = EV_ALL); ///< Add file handle event callback
/**< add() will add a callback to the Scheduler. The
- callbeck will be called for the given type of event on
- the given arbitrary file-descriptor or
- handle-like object. If there already is a Callback
- register ed for one of the events requested, the new
- handler will replace the old one.
- \param[in] handle file descriptor or handle providing
- the Handle interface defined above.
- \param[in] cb callback
- \param[in] eventMask arbitrary combination via '|'
- operator of EventId designators. */
- template <class Handle>
+ callbeck will be called for the given type of event on
+ the given arbitrary file-descriptor or
+ handle-like object. If there already is a Callback
+ register ed for one of the events requested, the new
+ handler will replace the old one.
+ \param[in] handle file descriptor or handle providing
+ the Handle interface defined above.
+ \param[in] cb callback
+ \param[in] eventMask arbitrary combination via '|'
+ operator of EventId designators. */
+ template <class Handle>
void remove(Handle const & handle, int eventMask = EV_ALL); ///< Remove event callback
/**< remove() will remove any callback registered for any of
- the given events on the given file descriptor or handle
- like object.
- \param[in] handle file descriptor or handle providing
- the Handle interface defined above.
- \param[in] eventMask arbitrary combination via '|'
- operator of EventId designators. */
-
- void timeout(unsigned long timeout, TimerCallback const & cb); ///< Add timeout event
+ the given events on the given file descriptor or handle
+ like object.
+ \param[in] handle file descriptor or handle providing
+ the Handle interface defined above.
+ \param[in] eventMask arbitrary combination via '|'
+ operator of EventId designators. */
+
+ void timeout(unsigned long timeout, TimerCallback const & cb); ///< Add timeout event
/**< \param[in] timeout timeout in milliseconds
- \param[in] cb callback to call after \a timeout
- milliseconds
- \todo Return some kind of handle/pointer and add
- support to update or revoke a timeout */
+ \param[in] cb callback to call after \a timeout
+ milliseconds
+ \todo Return some kind of handle/pointer and add
+ support to update or revoke a timeout */
void process(); ///< Event handler main loop
/**< This member must be called at some time to enter the
- event handler main loop. Only while this function is
- running any events are handled. The call will return
- only, if any callback calls terminate(). */
+ event handler main loop. Only while this function is
+ running any events are handled. The call will return
+ only, if any callback calls terminate(). */
void terminate(); ///< Called by callbacks to terminate the main loop
/**< This member may be called by any callback to tell the
- main loop to terminate. The main loop will return to
- it's caller after the currently running callback
- returns. */
+ main loop to terminate. The main loop will return to
+ it's caller after the currently running callback
+ returns. */
protected:
private:
- typedef boost::function<void (EventId)> SimpleCallback;
+ typedef boost::function<void (EventId)> SimpleCallback;
Scheduler();
-
+
void do_add(int fd, SimpleCallback const & cb, int eventMask = EV_ALL);
void do_remove(int fd, int eventMask = EV_ALL);
- /** \brief Descriptor event specification
- \internal */
- struct EventSpec
+ /** \brief Descriptor event specification
+ \internal */
+ struct EventSpec
{
SimpleCallback cb_read;
SimpleCallback cb_prio;
int epollMask() const;
};
-
- /** \brief Timer event specification
- \internal */
- struct TimerSpec
- {
- TimerSpec() : timeout(), cb() {}
+
+ /** \brief Timer event specification
+ \internal */
+ struct TimerSpec
+ {
+ TimerSpec() : timeout(), cb() {}
TimerSpec(unsigned long long timeout_, TimerCallback cb_)
: timeout(timeout_), cb(cb_) {}
- bool operator< (TimerSpec const & other) const
- { return timeout > other.timeout; }
-
- unsigned long long timeout;
- TimerCallback cb;
- };
-
+ bool operator< (TimerSpec const & other) const
+ { return timeout > other.timeout; }
+
+ unsigned long long timeout;
+ TimerCallback cb;
+ };
+
typedef std::map<int,EventSpec> FdTable;
- typedef std::priority_queue<TimerSpec> TimerQueue;
+ typedef std::priority_queue<TimerSpec> TimerQueue;
FdTable fdTable_;
- TimerQueue timerQueue_;
+ TimerQueue timerQueue_;
int epollFd_;
bool terminate_;
};
/** \brief Default file descriptor accessor
-
- retrieve_filehandle() provides the Scheduler with support for explicit file descriptors as
- file handle argument.
- \relates Scheduler
+ retrieve_filehandle() provides the Scheduler with support for explicit file descriptors as
+ file handle argument.
+
+ \relates Scheduler
*/
int retrieve_filehandle(int fd);
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
using namespace senf;
namespace {
-
+
char const * SOCK_PATH = "/tmp/sched_test.sock";
-
+
void error(char const * fn, char const * proc="")
{
std::cerr << "\n" << proc << fn << ": " << strerror(errno) << std::endl;
error("fork");
return 0;
}
-
+
sleep(1); // Wait for the server socket to be opened
return pid;
}
Scheduler::instance().terminate();
}
- void timeout()
+ void timeout()
{
- Scheduler::instance().terminate();
+ Scheduler::instance().terminate();
}
-
+
struct HandleWrapper
{
HandleWrapper(int fd,std::string const & tag) : fd_(fd), tag_(tag) {}
bool is_close(MicroTime a, MicroTime b)
{
- return (a<b ? b-a : a-b) < 10100; // a little bit over 10ms
+ return (a<b ? b-a : a-b) < 10100; // a little bit over 10ms
}
-
+
}
BOOST_AUTO_UNIT_TEST(scheduler)
memset(&sun,0,sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path,SOCK_PATH);
-
+
if (connect(sock,(struct sockaddr*)&sun,sizeof(sun))<0) {
error("connect");
BOOST_FAIL("connect");
BOOST_CHECK_PREDICATE( is_close, (now()) (t+100*1000) );
BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
BOOST_CHECK_PREDICATE( is_close, (now()) (t+200*1000) );
-
+
HandleWrapper handle(sock,"TheTag");
BOOST_CHECK_NO_THROW( Scheduler::instance().add(handle,&handleCallback,Scheduler::EV_WRITE) );
strcpy(buffer,"WRITE");
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Copyright (C) 2006
+// Copyright (C) 2006
/** \file
\brief WriteHelper non-inline template implementation */
offset_(0), errno_(0)
{
senf::Scheduler::instance()
- .add(handle_, boost::bind(&WriteHelper::dispatchProcess, ptr(this), _1, _2),
- senf::Scheduler::EV_WRITE);
+ .add(handle_, boost::bind(&WriteHelper::dispatchProcess, ptr(this), _1, _2),
+ senf::Scheduler::EV_WRITE);
}
template <class Handle>
const
{
if (offset_ > 0) {
- data_.erase(0,offset_);
- offset_ = 0;
+ data_.erase(0,offset_);
+ offset_ = 0;
}
return data_;
}
{
ptr guard (this); // To ensure, 'this' is deleted only after this method terminates ...
senf::Scheduler::instance()
- .remove(handle_, senf::Scheduler::EV_WRITE);
+ .remove(handle_, senf::Scheduler::EV_WRITE);
}
template <class Handle>
{
/** \fixme Move the done() calls to outside the try/catch block */
try {
- if (event != senf::Scheduler::EV_WRITE)
- throw senf::SystemException(EPIPE);
- offset_ += handle.write(data_.data()+offset_,data_.size()-offset_);
- if (offset_ >= data_.size()) {
- data_.erase();
- done();
- }
+ if (event != senf::Scheduler::EV_WRITE)
+ throw senf::SystemException(EPIPE);
+ offset_ += handle.write(data_.data()+offset_,data_.size()-offset_);
+ if (offset_ >= data_.size()) {
+ data_.erase();
+ done();
+ }
}
catch (senf::SystemException const & ex) {
- errno_ = ex.err;
- done();
+ errno_ = ex.err;
+ done();
}
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Copyright (C) 2006
+// Copyright (C) 2006
/** \file
\brief WriteHelper inline template implementation */
const
{
if (errno_ != 0)
- throw senf::SystemException(errno_);
+ throw senf::SystemException(errno_);
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Copyright (C) 2006
+// Copyright (C) 2006
/** \file
\brief WriteHelper public header */
namespace senf {
/** \brief Asyncronous writing helper
-
- This class provides a simple asyncronous writing facility. This helper will register with
- the Scheduler to write the requested data. It will stay registered until the data has benen
- completely sent or some error condition is encountered. As soon as the WriteHelper is done,
- the callback will be called.
- The WriteHelper accepts the same flexible file handle interfaces as the Scheduler.
+ This class provides a simple asyncronous writing facility. This helper will register with
+ the Scheduler to write the requested data. It will stay registered until the data has benen
+ completely sent or some error condition is encountered. As soon as the WriteHelper is done,
+ the callback will be called.
- The callback must take a WriteHelper::ptr argument. Using this WriteHelper instance, the
- callback can access the state information and check the termination status.
+ The WriteHelper accepts the same flexible file handle interfaces as the Scheduler.
- \todo Add additional interface to better access the intermediate status (data sent so far)
+ The callback must take a WriteHelper::ptr argument. Using this WriteHelper instance, the
+ callback can access the state information and check the termination status.
+
+ \todo Add additional interface to better access the intermediate status (data sent so far)
*/
template <class Handle>
class WriteHelper
- : public senf::intrusive_refcount
+ : public senf::intrusive_refcount
{
public:
///////////////////////////////////////////////////////////////////////////
// Types
- typedef boost::intrusive_ptr<WriteHelper> ptr; ///< Smart pointer type for this class
- typedef boost::function<void (ptr)> Callback; ///< Callback type
+ typedef boost::intrusive_ptr<WriteHelper> ptr; ///< Smart pointer type for this class
+ typedef boost::function<void (ptr)> Callback; ///< Callback type
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
- static ptr dispatch(Handle handle, std::string data, Callback callback);
+ static ptr dispatch(Handle handle, std::string data, Callback callback);
///< Register new WriteHelper instance
/**< The registered callback will be called after all \a
- data has been sent or when some error condition is
- encountered.
- \param[in] handle file descriptor or handle providing
- the Handle interface defined above.
- \param[in] data data to send
- \param[in] cb callback
- \returns smart pointer to new WriteHelper instance */
+ data has been sent or when some error condition is
+ encountered.
+ \param[in] handle file descriptor or handle providing
+ the Handle interface defined above.
+ \param[in] data data to send
+ \param[in] cb callback
+ \returns smart pointer to new WriteHelper instance */
///@}
///////////////////////////////////////////////////////////////////////////
- Handle handle() const;
+ Handle handle() const;
- std::string const & data() const; ///< Return the data
+ std::string const & data() const; ///< Return the data
/**< After all data has been sent, this member will return
- an empty string. Until then, the complete string will
- be returned. */
+ an empty string. Until then, the complete string will
+ be returned. */
- bool complete() const; ///< Check wether the write has completed successfully
- bool error() const; ///< Check for error condition
- void throw_error() const; ///< If an error occured, throw it
+ bool complete() const; ///< Check wether the write has completed successfully
+ bool error() const; ///< Check for error condition
+ void throw_error() const; ///< If an error occured, throw it
- void revoke(); ///< Remove the WriteHelper from the scheduler
+ void revoke(); ///< Remove the WriteHelper from the scheduler
protected:
private:
- WriteHelper(Handle handle, std::string data, Callback callback);
+ WriteHelper(Handle handle, std::string data, Callback callback);
- static void dispatchProcess(ptr helper, Handle handle, senf::Scheduler::EventId event);
- void process(Handle handle, senf::Scheduler::EventId event);
- void done();
+ static void dispatchProcess(ptr helper, Handle handle, senf::Scheduler::EventId event);
+ void process(Handle handle, senf::Scheduler::EventId event);
+ void done();
- Handle handle_;
- mutable std::string data_;
- Callback callback_;
+ Handle handle_;
+ mutable std::string data_;
+ Callback callback_;
- mutable std::string::size_type offset_;
- int errno_;
+ mutable std::string::size_type offset_;
+ int errno_;
};
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Unit tests
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id: main.test.cc 32 2006-03-23 16:24:56Z sbund $
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
std::cout << " " << ascii << "\n";
ascii = "";
}
- std::cout << " "
- << std::hex << std::setw(4) << std::setfill('0')
+ std::cout << " "
+ << std::hex << std::setw(4) << std::setfill('0')
<< offset << ' ';
break;
case BLOCK_SIZE/2:
ascii += ' ';
break;
}
- std::cout << ' ' << std::hex << std::setw(2) << std::setfill('0')
+ std::cout << ' ' << std::hex << std::setw(2) << std::setfill('0')
<< unsigned(*i);
ascii += (*i >= ' ' && *i < 126) ? *i : '.';
}
senf::PacketSocketHandle sock;
sock.bind(senf::LLSocketAddress("eth0"));
// sock.protocol().promisc("eth0",senf::PacketProtocol::Promiscuous);
-
+
while (true) { // forever
std::string data (sock.read());
senf::EthernetPacket::ptr packet (
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief AddressingPolicy for non-addressable sockets
- This is different from UndefinedAddressingPolicy (which is the
- same as AddressingPolicyBase). This policy class defines the
- addressing -- it explicitly states, that the socket does not
- support any addressing.
+ This is different from UndefinedAddressingPolicy (which is the
+ same as AddressingPolicyBase). This policy class defines the
+ addressing -- it explicitly states, that the socket does not
+ support any addressing.
*/
struct NoAddressingPolicy : public AddressingPolicyBase
{};
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
const
{
/** \bug Check, why this fails with ENOFILE (!!!!) at least when
- called from a tcp socket.Maybe this is only available for
- datagram sockets ? That could make sense from the description
- (what is the last packet passed to the user on a stream
- socket?) Further investigation necessary ... */
+ called from a tcp socket.Maybe this is only available for
+ datagram sockets ? That could make sense from the description
+ (what is the last packet passed to the user on a stream
+ socket?) Further investigation necessary ... */
struct timeval tv;
if (::ioctl(body().fd(), SIOCGSTAMP, &tv) < 0)
throw SystemException(errno);
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/// @{
/** \brief Protocol facet providing basic BSD socket functionality
-
- BSDSocketProtocol provides the basic BSD socket API as shared by all BSD sockets.
+
+ BSDSocketProtocol provides the basic BSD socket API as shared by all BSD sockets.
*/
class BSDSocketProtocol
: public virtual SocketProtocol
public:
std::pair<bool,unsigned> linger() const; ///< Return current linger status
/**< The value is returned in an std:pair. the first element
- is \c true, if linger is active. The second value is
- the linger timeout in seconds.
- \returns linger state (enable disabled) and linger
- timeout */
+ is \c true, if linger is active. The second value is
+ the linger timeout in seconds.
+ \returns linger state (enable disabled) and linger
+ timeout */
void linger(bool enable, unsigned timeout=0) const; ///< Change linger status
/**< If linger is enabled, the timeout value specifies, how
- long to wait before returning while data is unsent in
- seconds. If this value is 0, a close() might wait
- forvever.
- \param[in] enable \c true to activate linger
- \param[in] timeout linger timeout in seconds */
+ long to wait before returning while data is unsent in
+ seconds. If this value is 0, a close() might wait
+ forvever.
+ \param[in] enable \c true to activate linger
+ \param[in] timeout linger timeout in seconds */
struct timeval timestamp() const; ///< Return packet timestamp of last packet
/**< The returned timestamp represents the time, at which
- the last network packet passed to the user has been
- received from the network. This allows precise network
- timing.
- \returns timestamp when packet was received */
+ the last network packet passed to the user has been
+ received from the network. This allows precise network
+ timing.
+ \returns timestamp when packet was received */
};
/** \brief Protocol facat providing basic connection oriented BSD socket functions
-
- AddressableBSDSocketProtocol provides the BSD socket API as it generically applies to
- addressable (connection oriented) sockets.
+
+ AddressableBSDSocketProtocol provides the BSD socket API as it generically applies to
+ addressable (connection oriented) sockets.
*/
class AddressableBSDSocketProtocol
: public virtual SocketProtocol
public:
bool reuseaddr() const; ///< Return current reuseaddr state
/**< \returns \c true if \c SO_REUSEADDR is currently
- enabled, \c false otherwise*/
+ enabled, \c false otherwise*/
void reuseaddr(bool value) const; ///< Set reuseraddr state
/**< A \c true value enables \c SO_REUSEADDR, \c false will
- disable it.
- \param[in] value new \c SO_REUSEADDR state */
+ disable it.
+ \param[in] value new \c SO_REUSEADDR state */
};
/// @}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// Linux doubles the bufer size on setting the SNDBUF to cater for internal
// headers. We fix this up here .. (see lkml FAQ)
return size/2;
-
+
}
prefix_ void senf::SocketBufferingPolicy::sndbuf(FileHandle handle, unsigned size)
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief BufferingPolicy implementing standard socket buffering
- This policy class implements standard BSD socket buffering.
+ This policy class implements standard BSD socket buffering.
- \todo Shouldn't this be dependent on Read / WritePolicy ?
+ \todo Shouldn't this be dependent on Read / WritePolicy ?
*/
struct SocketBufferingPolicy : public BufferingPolicyBase
{
static unsigned rcvbuf(FileHandle handle);
///< Check receive buffer size
- /**< \param[in] handle socket handle to check
- \returns size of receive buffer in bytes */
+ /**< \param[in] handle socket handle to check
+ \returns size of receive buffer in bytes */
static void rcvbuf(FileHandle handle, unsigned size);
///< Change receive buffer size
/**< \param[in] handle socket handle
- \param[in] size new receive buffer size */
+ \param[in] size new receive buffer size */
static unsigned sndbuf(FileHandle handle);
///< Check send buffer size
/**< \param[in] handle socket handle to check
- \returns size of send buffer in bytes */
+ \returns size of send buffer in bytes */
static void sndbuf(FileHandle handle, unsigned size);
///< Change size of send buffer
/**< \param[in] handle socket handle
- \param[in] size new send buffer size */
+ \param[in] size new send buffer size */
};
/// @}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
prefix_ void senf::ClientSocketHandle<Policy>::read(std::string & buffer, unsigned limit)
{
unsigned nread = available();
- if (limit>0 && nread>limit)
- nread = limit;
+ if (limit>0 && nread>limit)
+ nread = limit;
/** \fixme This is not necessary correct and more or less a hack ... */
buffer.assign(nread,0);
unsigned rv = this->read(const_cast<char *>(buffer.data()),nread);
// DatagramFramingPolicy sockets will ALWAYS either write the
// complete datagram or nothing at all
while (written < data.size()) {
- unsigned n = this->write(data.data()+written,data.size()-written);
+ unsigned n = this->write(data.data()+written,data.size()-written);
if (n == 0)
throw SystemException(EPIPE);
written += n;
{
unsigned nread = this->protocol().available();
if (nread == 0 && this->blocking()) {
- // We have to block explicitly here so we can return the
- // number of bytes available explicitly. If no more date can
- // be expected to arive (i.e. the other end has closed the
- // connection), the socket will always be in the readable
- // state. This is the only case when available() will return
- // 0.
- this->waitReadable();
- nread = this->protocol().available();
+ // We have to block explicitly here so we can return the
+ // number of bytes available explicitly. If no more date can
+ // be expected to arive (i.e. the other end has closed the
+ // connection), the socket will always be in the readable
+ // state. This is the only case when available() will return
+ // 0.
+ this->waitReadable();
+ nread = this->protocol().available();
}
return nread;
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
-
+
/// \addtogroup handle_group
/// @{
-
+
template <class Policy> class ServerSocketHandle;
/** \brief Generic SocketHandle with client interface
-
- This class provides the client side policy interface of the socket
- abstraction. ClientSocketHandle defines the complete policy interface. It does not implement
- any functionality itself however. All calls are forward to the following policy classes:
-
- <table class="senf">
- <tr><th>ClientSocketHandle member</th> <th>Policy member</th></tr>
- <tr><td>read()</td> <td>ReadPolicy::read (\ref senf::ReadPolicyBase)</td></tr>
- <tr><td>readfrom()</td> <td>ReadPolicy::readfrom (\ref senf::ReadPolicyBase)</td></tr>
- <tr><td>write()</td> <td>WritePolicy::write (\ref senf::WritePolicyBase)</td></tr>
- <tr><td>writeto()</td> <td>WritePolicy::writeto (\ref senf::WritePolicyBase)</td></tr>
- <tr><td>connect()</td> <td>AddressingPolicy::connect (\ref senf::AddressingPolicyBase)</td></tr>
- <tr><td>bind()</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td></tr>
- <tr><td>peer()</td> <td>AddressingPolicy::peer (\ref senf::AddressingPolicyBase)</td></tr>
- <tr><td>local()</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td></tr>
- <tr><td>rcvbuf()</td> <td>BufferingPolicy::sndbuf (\ref senf::BufferingPolicyBase)</td></tr>
- <tr><td>sndbuf()</td> <td>BufferingPolicy::rcvbuf (\ref senf::BufferingPolicyBase)</td></tr>
- </table>
-
- It is important to note, that not all members are always accessible. Which are depends on
- the \c Policy template argument. If any of the policy axis is left unspecified the
- corresponding members will not be callable (you will get a compile time error). Even if
- every policy axis is defined, some members might (and will) not exist if they are
- meaningless for the protocol of the socket. This depends on the exact policy.
-
- To find out, which members are available, you have to check the documentation of the policy
- classes. You can also find a summary of all members available in the leaf protocol class
- documentation.
-
- \todo Move all not template-parameter dependent code into a non-template base class
-
- \idea Give SocketHandle (and therefore ClientSocketHandle and ServerSocketHandle) a \c
- protocol() template member and an additional template arg \c Policies. This arg should be a
- typelist of Poclicy classes which can be accessed. You use protocol<ProtocolClass>() to
- access a protocol class. \c Policies can of course be underspecified or even empty.
-
- \idea add more flexible read/write members for a) boost::arrays and arrays of other types b)
- std::vector (which uses contiguous memory ..) c) other random-access containers (we should
- use some configurable trait class to identify containers with contiguous storage). Probably
- we should just use a generic Boost.Range interface. Here we again come to the point: make
- all except the most basic members be non-member algorithms ? this would make the
- configuration of such extenden members more flexible.
-
- \see \ref policy_group \n
+
+ This class provides the client side policy interface of the socket
+ abstraction. ClientSocketHandle defines the complete policy interface. It does not implement
+ any functionality itself however. All calls are forward to the following policy classes:
+
+ <table class="senf">
+ <tr><th>ClientSocketHandle member</th> <th>Policy member</th></tr>
+ <tr><td>read()</td> <td>ReadPolicy::read (\ref senf::ReadPolicyBase)</td></tr>
+ <tr><td>readfrom()</td> <td>ReadPolicy::readfrom (\ref senf::ReadPolicyBase)</td></tr>
+ <tr><td>write()</td> <td>WritePolicy::write (\ref senf::WritePolicyBase)</td></tr>
+ <tr><td>writeto()</td> <td>WritePolicy::writeto (\ref senf::WritePolicyBase)</td></tr>
+ <tr><td>connect()</td> <td>AddressingPolicy::connect (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>bind()</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>peer()</td> <td>AddressingPolicy::peer (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>local()</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>rcvbuf()</td> <td>BufferingPolicy::sndbuf (\ref senf::BufferingPolicyBase)</td></tr>
+ <tr><td>sndbuf()</td> <td>BufferingPolicy::rcvbuf (\ref senf::BufferingPolicyBase)</td></tr>
+ </table>
+
+ It is important to note, that not all members are always accessible. Which are depends on
+ the \c Policy template argument. If any of the policy axis is left unspecified the
+ corresponding members will not be callable (you will get a compile time error). Even if
+ every policy axis is defined, some members might (and will) not exist if they are
+ meaningless for the protocol of the socket. This depends on the exact policy.
+
+ To find out, which members are available, you have to check the documentation of the policy
+ classes. You can also find a summary of all members available in the leaf protocol class
+ documentation.
+
+ \todo Move all not template-parameter dependent code into a non-template base class
+
+ \idea Give SocketHandle (and therefore ClientSocketHandle and ServerSocketHandle) a \c
+ protocol() template member and an additional template arg \c Policies. This arg should be a
+ typelist of Poclicy classes which can be accessed. You use protocol<ProtocolClass>() to
+ access a protocol class. \c Policies can of course be underspecified or even empty.
+
+ \idea add more flexible read/write members for a) boost::arrays and arrays of other types b)
+ std::vector (which uses contiguous memory ..) c) other random-access containers (we should
+ use some configurable trait class to identify containers with contiguous storage). Probably
+ we should just use a generic Boost.Range interface. Here we again come to the point: make
+ all except the most basic members be non-member algorithms ? this would make the
+ configuration of such extenden members more flexible.
+
+ \see \ref policy_group \n
\ref protocol_group
*/
template <class Policy>
///////////////////////////////////////////////////////////////////////////
// Types
- /// Address type from the addressing policy
+ /// Address type from the addressing policy
typedef typename Policy::AddressingPolicy::Address Address;
- /// 'Best' type for passing address as parameter
- /** Depending on the type of \c Address, this will be either <tt>Address</tt> or <tt>Address
- const &</tt>. See <a href="http://www.boost.org/libs/utility/call_traits.htm"
- class="ext">call_traits documentation in the Boost.Utility library\endlink.</a>
- */
+ /// 'Best' type for passing address as parameter
+ /** Depending on the type of \c Address, this will be either <tt>Address</tt> or <tt>Address
+ const &</tt>. See <a href="http://www.boost.org/libs/utility/call_traits.htm"
+ class="ext">call_traits documentation in the Boost.Utility library\endlink.</a>
+ */
typedef typename boost::call_traits<Address>::param_type AddressParam;
- /// Corresponding server socket handle with the same policy
- /** This class will probably only be usable, if the \c CommunicationPolicy is \c
- ConnectedCommunicationPolicy and the \c AddressingPolicy is not \c
- NoAddressingPolicy. */
+ /// Corresponding server socket handle with the same policy
+ /** This class will probably only be usable, if the \c CommunicationPolicy is \c
+ ConnectedCommunicationPolicy and the \c AddressingPolicy is not \c
+ NoAddressingPolicy. */
typedef ServerSocketHandle<Policy> ServerSocketHandle;
///////////////////////////////////////////////////////////////////////////
typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type * = 0);
template <class OtherPolicy>
- typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const &
+ typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const &
operator=(ClientSocketHandle<OtherPolicy> other);
///@}
///\name Reading and Writing
///@{
- /** \brief Read data from socket
+ /** \brief Read data from socket
- If the sockets \c FramingPolicy is \c DatagramFramingPolicy, every read() command will
- return a single datagram. If the sockets FramingPolicy is StreamFraming, the operation will
- return as much data as possible from the socket buffer. However it cannot be guaranteed,
- that the socket buffer will be empty after read() returns.
+ If the sockets \c FramingPolicy is \c DatagramFramingPolicy, every read() command will
+ return a single datagram. If the sockets FramingPolicy is StreamFraming, the operation will
+ return as much data as possible from the socket buffer. However it cannot be guaranteed,
+ that the socket buffer will be empty after read() returns.
- \attention If the space available for the data read is limited, the read will return no
- more than that amount of data. For a datagram socket, a full datagram is still dequed
- from the socket buffer, the remainder of the datagram will be lost.
+ \attention If the space available for the data read is limited, the read will return no
+ more than that amount of data. For a datagram socket, a full datagram is still dequed
+ from the socket buffer, the remainder of the datagram will be lost.
- There are three variants of read which differ in how they return the read string.
+ There are three variants of read which differ in how they return the read string.
- \throws senf::SystemException
+ \throws senf::SystemException
- This variant will read up to \c limit bytes from the
- socket and return them as a \c std::string object.
+ This variant will read up to \c limit bytes from the
+ socket and return them as a \c std::string object.
- On a blocking socket, this member will \e always return some data (as long as the socket
- has not been closed at the other end) and will block, if no data is available now. If
- you do not want to block, you \e must make the socket non-blocking (using
- FileHandle::blocking()).
+ On a blocking socket, this member will \e always return some data (as long as the socket
+ has not been closed at the other end) and will block, if no data is available now. If
+ you do not want to block, you \e must make the socket non-blocking (using
+ FileHandle::blocking()).
- \param[in] limit Maximum number of bytes to read or 0 if unlimited.
- \returns data read
-
- \implementation The read() family of members will use standard POSIX \c read calls, not
- \c recv.
- */
+ \param[in] limit Maximum number of bytes to read or 0 if unlimited.
+ \returns data read
+
+ \implementation The read() family of members will use standard POSIX \c read calls, not
+ \c recv.
+ */
std::string read (unsigned limit=0);
void read (std::string & buffer, unsigned limit=0);
///< Read data into string buffer
/**< On a blocking socket, this member will \e always return
- some data (as long as the socket has not been closed at
- the other end) and will block, if no data is available
- now. If you do not want to block, you \e must make the
- socket non-blocking (using FileHandle::blocking()).
- \param[out] buffer data read
- \param[in] limit Maximum number of buytes to read or 0
- if unlimited
- \see \ref read() */
+ some data (as long as the socket has not been closed at
+ the other end) and will block, if no data is available
+ now. If you do not want to block, you \e must make the
+ socket non-blocking (using FileHandle::blocking()).
+ \param[out] buffer data read
+ \param[in] limit Maximum number of buytes to read or 0
+ if unlimited
+ \see \ref read() */
unsigned read (char * buffer, unsigned size);
///< Read data into memory area
/**< This variant will read data into the memory area at \c
- buffer of size \c size. This is the most performant
- version of read().
- \param[in] buffer address of buffer to store data at
- \param[in] size size of memory buffer
- \returns Number of bytes read
- \see \ref read() */
+ buffer of size \c size. This is the most performant
+ version of read().
+ \param[in] buffer address of buffer to store data at
+ \param[in] size size of memory buffer
+ \returns Number of bytes read
+ \see \ref read() */
- /** \brief Read data from unconnected socket returning address
+ /** \brief Read data from unconnected socket returning address
- This member behaves like read() but should only be available, if the sockets \c
- CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is
- not \c NoAddressingPolicy. The readfrom() family will in addition to the data return the
- address of the sender.
+ This member behaves like read() but should only be available, if the sockets \c
+ CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is
+ not \c NoAddressingPolicy. The readfrom() family will in addition to the data return the
+ address of the sender.
- \throws senf::SystemException
+ \throws senf::SystemException
- This variant will return the data read and the address as a std::pair.
+ This variant will return the data read and the address as a std::pair.
- \returns \c std::pair of data read (a string) and the peers address
+ \returns \c std::pair of data read (a string) and the peers address
- \todo Add \c limit argument
+ \todo Add \c limit argument
- \implementation The readfrom() family of members will use \c recvfrom from the BSD
- socket API.
- */
- std::pair<std::string, Address>
+ \implementation The readfrom() family of members will use \c recvfrom from the BSD
+ socket API.
+ */
+ std::pair<std::string, Address>
readfrom ();
void readfrom (std::string & buffer, Address & from);
///< Read data into string buffer
/**< This variant will return the result in the locations
- passed in
- \param[out] buffer data read
- \param[out] from peer address
- \see \ref readfrom() */
+ passed in
+ \param[out] buffer data read
+ \param[out] from peer address
+ \see \ref readfrom() */
unsigned readfrom (char * buffer, unsigned size, Address & from);
///< Read data into memory byffer
/**< This variant will read data into the memory area at \c
- buffer of size \c size. This is the most performant
- version of readfrom().
- \param[in] buffer address of buffer to store data at
- \param[in] size size of bnuffer
- \param[out] from peer address
- \returns Number of bytes read
- \see \ref readfrom() */
-
-
- /** \brief Write data to socket
-
- The write() family of members will write out the data to the socket. If the sockets \c
- FramingPolicy is \c DatagramFramingPolicy, every write() call will result in one
- datagram.
-
- A single write call might depending on the circumstances write only part of the data.
-
- There are two variants of thie member
-
- \throws senf::SystemException
-
-
- This variant will write out the string \c data.
-
- \param[in] data Data to write
- \returns number of bytes written
- \todo Make this member write the complete string if the socket is blocking
- \implementation The write() family of members will use POSIX \c write calls, not \c
- send.
- */
+ buffer of size \c size. This is the most performant
+ version of readfrom().
+ \param[in] buffer address of buffer to store data at
+ \param[in] size size of bnuffer
+ \param[out] from peer address
+ \returns Number of bytes read
+ \see \ref readfrom() */
+
+
+ /** \brief Write data to socket
+
+ The write() family of members will write out the data to the socket. If the sockets \c
+ FramingPolicy is \c DatagramFramingPolicy, every write() call will result in one
+ datagram.
+
+ A single write call might depending on the circumstances write only part of the data.
+
+ There are two variants of thie member
+
+ \throws senf::SystemException
+
+
+ This variant will write out the string \c data.
+
+ \param[in] data Data to write
+ \returns number of bytes written
+ \todo Make this member write the complete string if the socket is blocking
+ \implementation The write() family of members will use POSIX \c write calls, not \c
+ send.
+ */
unsigned write (std::string const & data);
unsigned write (char const * buffer, unsigned size);
///< Write data to socket from memory buffer
/**< \param[in] buffer address of buffer to write
- \param[in] size amount of data to write
- \returns Number of bytes written
- \see \ref write() */
+ \param[in] size amount of data to write
+ \returns Number of bytes written
+ \see \ref write() */
+
+ /** \brief Write data to unconnected socket
- /** \brief Write data to unconnected socket
+ This member behaves like write() but should only be available, if the sockets \c
+ CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is
+ not \c NoAddressingPolicy. The writeto() family of members takes the target address as
+ an additional argument.
- This member behaves like write() but should only be available, if the sockets \c
- CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is
- not \c NoAddressingPolicy. The writeto() family of members takes the target address as
- an additional argument.
+ There are two variants of this member.
- There are two variants of this member.
+ \throw senf::SystemException
- \throw senf::SystemException
-
- This variant will send the string \c data to the peer \c addr.
+ This variant will send the string \c data to the peer \c addr.
- \param[in] addr Address of peer to send data to
- \param[in] data data to send
- \returns Number of bytes written
- */
- unsigned writeto (AddressParam addr, std::string const & data);
- unsigned writeto (AddressParam addr, char const * buffer, unsigned size);
+ \param[in] addr Address of peer to send data to
+ \param[in] data data to send
+ \returns Number of bytes written
+ */
+ unsigned writeto (AddressParam addr, std::string const & data);
+ unsigned writeto (AddressParam addr, char const * buffer, unsigned size);
///< Write data from memory buffer to unconnected socket
/**< \param[in] addr Address o fpeer to send data to
- \param[in] buffer address of buffer to write
- \param[in] size amount of data to write
- \returns Number of bytes written
- \see \ref writeto() */
+ \param[in] buffer address of buffer to write
+ \param[in] size amount of data to write
+ \returns Number of bytes written
+ \see \ref writeto() */
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Addressing
+ ///@{
- ///////////////////////////////////////////////////////////////////////////
- ///\name Addressing
- ///@{
+ /** \brief Connect to remote peer
- /** \brief Connect to remote peer
+ This member will establish a connection for addressable connection-oriented protocols
+ (that is, the CommunicationPolicy is ConnectedCommunicationPolicy and the
+ AddressingPolicy is not NoAddressingPolicy).
- This member will establish a connection for addressable connection-oriented protocols
- (that is, the CommunicationPolicy is ConnectedCommunicationPolicy and the
- AddressingPolicy is not NoAddressingPolicy).
+ \param[in] addr Address to connect to
- \param[in] addr Address to connect to
+ \throws senf::SystemException
+ */
+ void connect (AddressParam addr);
- \throws senf::SystemException
- */
- void connect (AddressParam addr);
+ /** \brief Set local address
- /** \brief Set local address
-
- For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set
- the local address of the socket.
+ For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set
+ the local address of the socket.
- \param[in] addr Local socket address to asign
+ \param[in] addr Local socket address to asign
- \throws senf::SystemException
- */
- void bind (AddressParam addr);
+ \throws senf::SystemException
+ */
+ void bind (AddressParam addr);
- /** \brief Query remote address
+ /** \brief Query remote address
- This member will return the address of the communication partner in addressable
- connection-oriented protocols (that is, the CommunicationPolicy is
- ConnectedCommunicationPolicy and the AddressingPolicy is not NoAddressingPolicy).
+ This member will return the address of the communication partner in addressable
+ connection-oriented protocols (that is, the CommunicationPolicy is
+ ConnectedCommunicationPolicy and the AddressingPolicy is not NoAddressingPolicy).
- There are two Variants of this member, one will return the address by value, the other
- takes a reference argument to elide the copy operation.
+ There are two Variants of this member, one will return the address by value, the other
+ takes a reference argument to elide the copy operation.
- \throws senf::SystemException
- */
- Address peer ();
- void peer (Address & addr);
+ \throws senf::SystemException
+ */
+ Address peer ();
+ void peer (Address & addr);
///< Query remote address
/**< \see \ref peer() */
- /** \brief Query local address
+ /** \brief Query local address
- This member will return the address of the local socket in addressable protocols
- (AddressingPolicy is not NoAddressingPolicy).
+ This member will return the address of the local socket in addressable protocols
+ (AddressingPolicy is not NoAddressingPolicy).
- There are two Variants of this member, one will return the address by value, the other
- takes a reference argument to elide the copy operation.
+ There are two Variants of this member, one will return the address by value, the other
+ takes a reference argument to elide the copy operation.
- \throws senf::SystemException
- */
- Address local ();
- void local (Address & addr);
+ \throws senf::SystemException
+ */
+ Address local ();
+ void local (Address & addr);
///< Query local address
/**< \see \ref local() */
- ///@}
+ ///@}
- ///////////////////////////////////////////////////////////////////////////
- ///\name Buffering
- ///@{
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Buffering
+ ///@{
- unsigned rcvbuf (); ///< Check size of receive buffer
+ unsigned rcvbuf (); ///< Check size of receive buffer
/**< \returns size of receive buffer in bytes */
- void rcvbuf (unsigned size);
+ void rcvbuf (unsigned size);
///< Set size of receive buffer
/**< \param[in] size size of receive buffer in bytes */
- unsigned sndbuf (); ///< Check size of send buffer
+ unsigned sndbuf (); ///< Check size of send buffer
/**< \returns size of send buffer in bytes */
- void sndbuf (unsigned size);
+ void sndbuf (unsigned size);
///< Set size of send buffer
/**< \param[in] size size of send buffer in bytes */
- ///@}
+ ///@}
- static ClientSocketHandle cast_static(FileHandle handle);
- static ClientSocketHandle cast_dynamic(FileHandle handle);
+ static ClientSocketHandle cast_static(FileHandle handle);
+ static ClientSocketHandle cast_dynamic(FileHandle handle);
- // we need to override both since SocketHandle is *not* polymorphic
- void state(SocketStateMap & map, unsigned lod=0);
- std::string dumpState(unsigned lod=0);
+ // we need to override both since SocketHandle is *not* polymorphic
+ void state(SocketStateMap & map, unsigned lod=0);
+ std::string dumpState(unsigned lod=0);
protected:
- ClientSocketHandle(FileHandle other, bool isChecked);
- explicit ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol,
- int fd = -1);
+ ClientSocketHandle(FileHandle other, bool isChecked);
+ explicit ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol,
+ int fd = -1);
private:
- unsigned available();
+ unsigned available();
- friend class senf::ServerSocketHandle<Policy>;
+ friend class senf::ServerSocketHandle<Policy>;
};
/// @}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
sl::test::SomeWritePolicy
>::policy OtherSocketPolicy;
typedef sl::SocketHandle<OtherSocketPolicy> OtherSocketHandle;
-
+
BOOST_CHECKPOINT("Copy-constructing socket handle");
OtherSocketHandle osh (myh);
BOOST_CHECKPOINT("Assigning socket handle");
osh = myh;
typedef sl::ClientSocketHandle<sl::test::SomeProtocol::Policy> SomeSocketHandle;
BOOST_CHECKPOINT("static_casting socket handle");
- SomeSocketHandle ssh =
+ SomeSocketHandle ssh =
sl::static_socket_cast<SomeSocketHandle>(osh);
BOOST_CHECK_NO_THROW( sl::dynamic_socket_cast<SomeSocketHandle>(osh) );
typedef sl::ClientSocketHandle<sl::MakeSocketPolicy<
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/// \addtogroup policy_impl_group
/// @{
-
+
template <class Policy> class ServerSocketHandle;
/** \brief CommunicationPolicy for connected sockets
- The ConnectedCommunicationPolicy provides support for standard BSD socket API based
- connected communication. It provides the server side listen() and accept() members.
+ The ConnectedCommunicationPolicy provides support for standard BSD socket API based
+ connected communication. It provides the server side listen() and accept() members.
*/
struct ConnectedCommunicationPolicy : public CommunicationPolicyBase
{
static void listen(FileHandle handle, unsigned backlog);
///< Enable establishing new connections on the socket
/**< \param[in] handle socket handle to enable reception on
- \param[in] backlog size of backlog queue
-
- \fixme listen probably makes no sense without accpept,
- so listen() should debend on AddressingPolicy
- too. */
+ \param[in] backlog size of backlog queue
+
+ \fixme listen probably makes no sense without accpept,
+ so listen() should debend on AddressingPolicy
+ too. */
template <class Policy>
- static int accept(ServerSocketHandle<Policy> handle,
+ static int accept(ServerSocketHandle<Policy> handle,
typename ServerSocketHandle<Policy>::Address & address,
typename IfAddressingPolicyIsNot<Policy,NoAddressingPolicy>::type * = 0);
///< accept a new connection on the socket.
/**< The accept() member will return a new client file
- descriptor. This file descriptor will be used by the
- ServerSocketHandle implementation to build a new
- ClientSocketHandle for the new connection.
-
- \param[in] handle socket handle to accept connection on
- \param[out] address address of newly connected remote
- peer
- \returns file descriptor of new client socket */
+ descriptor. This file descriptor will be used by the
+ ServerSocketHandle implementation to build a new
+ ClientSocketHandle for the new connection.
+
+ \param[in] handle socket handle to accept connection on
+ \param[out] address address of newly connected remote
+ peer
+ \returns file descriptor of new client socket */
private:
static int do_accept(FileHandle handle, struct sockaddr * addr, unsigned len);
};
/** \brief CommunicationPolicy for unconnected sockets
- This is different from UndefinedCommunicationPolicy (which is the same as
- CommunicationPolicyBase). This policy class defines the communication policy -- it
- explicitly states, that the socket does not support connected communication. This
- effektively disables ther ServerSocketHandle.
+ This is different from UndefinedCommunicationPolicy (which is the same as
+ CommunicationPolicyBase). This policy class defines the communication policy -- it
+ explicitly states, that the socket does not support connected communication. This
+ effektively disables ther ServerSocketHandle.
*/
struct UnconnectedCommunicationPolicy : public CommunicationPolicyBase
{};
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-/** \file
+/** \file
\brief FileHandle public header
*/
only classes, which may be created by the library user. You will
normally use these classes by naming a specific socket typedef
(e.g. senf::TCPv4ClientSocketHandle).
-
+
However, to aid writing flexible and generic code, the socket
library provides the senf::ClientSocketHandle and
senf::ServerSocketHandle class templates. These templates
#include "FileHandle.ih"
namespace senf {
-
+
/// \addtogroup handle_group
/// @{
-
+
/** \brief Basic file handle wrapper
- senf::FileHandle provides a simple wrapper for arbitrary file handles. It exposes only a
- minimal interface which does \e not include reading or writing (since some filehandles are
- not readable or writable or only using special function calls like sendto).
-
- The FileHandle class provides handle/body handling and uses automatic reference
- counting. The senf::FileHandle istance is very lightweight and should be used like a
- built-in type.
-
- \attention You should mostly pass around senf::FileHandle objects by \e value und not by
- reference.
-
- The FileHandle abstraction is only applicable to real filehandles. It is \e not possible to
- wrap any provider or consumer into a filehandle like interface using this wrapper. The
- wrapper will forward some calls directly to the underlying API without relying on virtual
- methods. This allows important members to be inlined.
-
- It is not possible to use the senf::FileHandle class directly since it does not have any
- public constructor. The FileHandle class is however the baseclass of all handle classes of
- the socket library.
-
- \section filehandle_new Writing senf::FileHandle derived classes
-
- To build a new FileHandle type you need to derive from senf::FileHandle. The derived class
- will have to call the protocted FileHandle constructor passing a new senf::FileBody
- instance. This instance may either be a simple senf::FileBody or a class derived from
- senf::FileBody.
-
- \todo Add public default constructor to allow declaration of (empty) senf::FileHandle
- variables.
+ senf::FileHandle provides a simple wrapper for arbitrary file handles. It exposes only a
+ minimal interface which does \e not include reading or writing (since some filehandles are
+ not readable or writable or only using special function calls like sendto).
+
+ The FileHandle class provides handle/body handling and uses automatic reference
+ counting. The senf::FileHandle istance is very lightweight and should be used like a
+ built-in type.
+
+ \attention You should mostly pass around senf::FileHandle objects by \e value und not by
+ reference.
+
+ The FileHandle abstraction is only applicable to real filehandles. It is \e not possible to
+ wrap any provider or consumer into a filehandle like interface using this wrapper. The
+ wrapper will forward some calls directly to the underlying API without relying on virtual
+ methods. This allows important members to be inlined.
+
+ It is not possible to use the senf::FileHandle class directly since it does not have any
+ public constructor. The FileHandle class is however the baseclass of all handle classes of
+ the socket library.
+
+ \section filehandle_new Writing senf::FileHandle derived classes
+
+ To build a new FileHandle type you need to derive from senf::FileHandle. The derived class
+ will have to call the protocted FileHandle constructor passing a new senf::FileBody
+ instance. This instance may either be a simple senf::FileBody or a class derived from
+ senf::FileBody.
+
+ \todo Add public default constructor to allow declaration of (empty) senf::FileHandle
+ variables.
*/
class FileHandle
- : public SafeBool<FileHandle>
+ : public SafeBool<FileHandle>
{
public:
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void close(); ///< Close filehandle
- /**< \throws senf::SystemException */
+ /**< \throws senf::SystemException */
void terminate(); ///< Close filehandle ignoring error conditions
bool readable() const; ///< Check, wether a read on the handle would not block
- ///< (ignoring blocking state)
+ ///< (ignoring blocking state)
void waitReadable() const; ///< Wait, until read on the handle would not block (ignoring
- ///< blocking state)
+ ///< blocking state)
bool writeable() const; ///< Check, wether a write on the handle would not block
- ///< (ignoring blocking state)
+ ///< (ignoring blocking state)
void waitWriteable() const; ///< Wait, until a write on the handle would not block
- ///< (ignoring blocking state)
+ ///< (ignoring blocking state)
bool blocking() const; ///< Return current blocking state
void blocking(bool status); ///< Set blocking state
bool eof() const; ///< Check EOF condition
- /**< Depending on the socket type, this might never return \p
- true.
-
- This member is somewhat problematic performance wise if
- called frequently since it relies on virtual
- functions. However, since the eof() handling is extremely
- protocol dependent, a policy based implementation does not
- seam feasible. */
+ /**< Depending on the socket type, this might never return \p
+ true.
+
+ This member is somewhat problematic performance wise if
+ called frequently since it relies on virtual
+ functions. However, since the eof() handling is extremely
+ protocol dependent, a policy based implementation does not
+ seam feasible. */
bool valid() const; ///< Check filehandle validity
- /**< Any operation besides valid() will fail on an invalid
- FileHandle */
+ /**< Any operation besides valid() will fail on an invalid
+ FileHandle */
- bool boolean_test() const; ///< Short for valid() && ! eof()
- /**< This is called when using a FileHandle instance in a boolen
- context
+ bool boolean_test() const; ///< Short for valid() && ! eof()
+ /**< This is called when using a FileHandle instance in a boolen
+ context
- See the performance comments for the eof() member */
+ See the performance comments for the eof() member */
int fd() const; ///< Return the raw FileHandle
protected:
explicit FileHandle(std::auto_ptr<FileBody> body);
- ///< create new FileHandle instance
- /**< The FileHandle instance will take over ownership over the
- given FileBody instance which must have been allocated using
- \c new. To configure the FileHandle behavior, A derived class
- may provide any class derived from FileBody here. */
+ ///< create new FileHandle instance
+ /**< The FileHandle instance will take over ownership over the
+ given FileBody instance which must have been allocated using
+ \c new. To configure the FileHandle behavior, A derived class
+ may provide any class derived from FileBody here. */
FileBody & body(); ///< Access body
FileBody const & body() const; ///< Access body in const context
static FileBody & body(FileHandle & handle); ///< Access body of another FileHandle instance
static FileBody const & body(FileHandle const & handle); ///< Access body of another
- ///< FileHandle instance in const context
+ ///< FileHandle instance in const context
- void fd(int fd); ///< Set raw filehandle
+ void fd(int fd); ///< Set raw filehandle
private:
FileBody::ptr body_;
};
/** \brief Adapt FileHandle to senf::Scheduler
- \related senf::FileHandle
+ \related senf::FileHandle
- \internal
+ \internal
- This function will be called by the Scheduler to retrieve the file descriptor of the
- FileHandle.
+ This function will be called by the Scheduler to retrieve the file descriptor of the
+ FileHandle.
*/
int retrieve_filehandle(FileHandle handle);
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief FileHandle referenced body
-
- \internal
- The senf::FileBody class formes the body part of the handle/body structure of the FileHandle
- interface. It manages the FileHandle data and is referenced by senf::FileHandle. It is
- automatically managed using reference counting.
+ \internal
- Since the senf::FileHandle class forwards most calls directly to the underlying
- senf::FileBody instance, most members are documented in senf::FileHandle.
+ The senf::FileBody class formes the body part of the handle/body structure of the FileHandle
+ interface. It manages the FileHandle data and is referenced by senf::FileHandle. It is
+ automatically managed using reference counting.
- \section filebody_new Writing senf::FileBody derived classes
+ Since the senf::FileHandle class forwards most calls directly to the underlying
+ senf::FileBody instance, most members are documented in senf::FileHandle.
- It is possible to write customized senf::FileBody derived body implementations. This
- implementation can then be used be a senf::FileHandle derived class to customize the
- FileHandle behavior. Handling the body directly by the handle class ensures, that no invalid
- handles can be created (a senf::FileHandle derived handle expecting a specific body type but
- pointing to a different body type).
+ \section filebody_new Writing senf::FileBody derived classes
- To customize the behavior, a virtual interface is provided. This interface only covers some
- basic funcionality which is only used infrequently during the lifetime of a FileHandle
- instance.
+ It is possible to write customized senf::FileBody derived body implementations. This
+ implementation can then be used be a senf::FileHandle derived class to customize the
+ FileHandle behavior. Handling the body directly by the handle class ensures, that no invalid
+ handles can be created (a senf::FileHandle derived handle expecting a specific body type but
+ pointing to a different body type).
+
+ To customize the behavior, a virtual interface is provided. This interface only covers some
+ basic funcionality which is only used infrequently during the lifetime of a FileHandle
+ instance.
*/
class FileBody
public:
///////////////////////////////////////////////////////////////////////////
// Types
-
+
typedef boost::intrusive_ptr<FileBody> ptr;
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
-
- explicit FileBody(int fd=-1); ///< Create new instance
- /**< You need to pass a real file descriptor to this
- 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() */
+
+ explicit FileBody(int fd=-1); ///< Create new instance
+ /**< You need to pass a real file descriptor to this
+ 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 copy
bool eof() const;
bool valid() const;
-
+
private:
///////////////////////////////////////////////////////////////////////////
// Virtual interface for subclasses to override
- virtual void v_close(); ///< Called to close the file descriptor
- /**< You should probably always call the global ::close()
- function in this member, however you might want to do
- some additional cleanup here. If the operation fails, you
- are allowed to throw (preferably a
- senf::SystemException).
-
- \throws senf::SystemException */
- virtual void v_terminate(); ///< Called to forcibly close the file descriptor
- /**< This member is called by the destructor (and by
- terminate()) to close the descriptor. This member must \e
- never throw, it should probably just ignore error
- conditions (there's not much else you can do) */
- virtual bool v_eof() const; ///< Called by eof()
- virtual bool v_valid() const; ///< Called by valid()
- /**< This member is only called, if the file descriptor is
- not -1 */
+ virtual void v_close(); ///< Called to close the file descriptor
+ /**< You should probably always call the global ::close()
+ function in this member, however you might want to do
+ some additional cleanup here. If the operation fails, you
+ are allowed to throw (preferably a
+ senf::SystemException).
+
+ \throws senf::SystemException */
+ virtual void v_terminate(); ///< Called to forcibly close the file descriptor
+ /**< This member is called by the destructor (and by
+ terminate()) to close the descriptor. This member must \e
+ never throw, it should probably just ignore error
+ conditions (there's not much else you can do) */
+ virtual bool v_eof() const; ///< Called by eof()
+ virtual bool v_valid() const; ///< Called by valid()
+ /**< This member is only called, if the file descriptor is
+ not -1 */
protected:
-
+
private:
bool pollCheck(int fd, bool incoming, bool block=false) const;
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
class FHandle : public senf::FileHandle
{
public:
- FHandle(int fd=-1)
+ FHandle(int fd=-1)
: senf::FileHandle(std::auto_ptr<senf::FileBody>(
new senf::FileBody(fd))) {}
- FHandle(std::string name)
+ FHandle(std::string name)
: senf::FileHandle(std::auto_ptr<senf::FileBody>(
new senf::FileBody()))
{
FHandle fh2(fh);
BOOST_CHECK_EQUAL(fh.fd(), fh2.fd());
-
+
BOOST_CHECK(fh.writeable());
BOOST_CHECK_NO_THROW(fh.close());
BOOST_CHECK_THROW(fh.close(),senf::SystemException);
BOOST_CHECK_NO_THROW(fh.terminate());
}
-
+
{
FHandle fh("/dev/zero");
BOOST_CHECK(fh.readable());
BOOST_FAIL(ex.what());
}
}
-
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/// @{
/** \brief FramingPolicy for stream oriented sockets
-
- This policy does not explicitly modify the SocketHAndle
- API. It however affects the semantics of the read and write
- operations. On a stream oriented socket, read() and write()
- operations may be combined, the boundary between separate
- write() calls will be lost on the receiving side.
+
+ This policy does not explicitly modify the SocketHAndle
+ API. It however affects the semantics of the read and write
+ operations. On a stream oriented socket, read() and write()
+ operations may be combined, the boundary between separate
+ write() calls will be lost on the receiving side.
*/
struct StreamFramingPolicy : public FramingPolicyBase
{};
/** \brief FramingPolicy for datagram oriented sockets
- This policy does not explicitly modify the SocketHAndle
- API. It however affects the semantics of the read and write
- operations. On a datagram socket, each read() or write() call
- we read or write a single datagram. Datagram boundaries are
- kept intact accross the network.
+ This policy does not explicitly modify the SocketHAndle
+ API. It however affects the semantics of the read and write
+ operations. On a datagram socket, each read() or write() call
+ we read or write a single datagram. Datagram boundaries are
+ kept intact accross the network.
*/
struct DatagramFramingPolicy : public FramingPolicyBase
{};
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
unsigned len)
{
while(1) {
- if (::connect(handle.fd(),addr,len) < 0)
+ if (::connect(handle.fd(),addr,len) < 0)
switch (errno) {
case EINPROGRESS: {
handle.waitWriteable();
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief Non-template implemenatation class of GenericAddressingPolicy template
- \internal
+ \internal
*/
struct GenericAddressingPolicy_Base
{
};
/** \brief Template for generic AddressingPolicy implementation based on the BSD socket API
-
- This template provides an implementation template to implement generic addressing policy
- classes which rely on the standard BSD socket API for their implementation
- (connect/bind/getsockname/getpeername).
-
- The \a Address template parameter specifies the address type of the addressing policy. This
- type must have two members: \c sockaddr_p() and \c sockaddr_len(). The first must return a
- <tt>struct sockaddr *</tt> to the address, the second must return the size of the address in
- bytes. The pointer returned by \c sockaddr_p() must be non-const if called on a non-const
- address. <em>The underlying socket address stored at that pointer might be
- modified</em>.
-
- This template class is inherited into addressing policy classes via private
- inheritance. Then the members supported by the respective addressing policy are made
- available via \c using declarations (See INet4AddressingPolicy for an Example).
-
- \idea We could explicitly provide open_sockaddr_p() and close_sockaddr_p()
- members. sockaddr_p could always return a const * whereas open_sockaddr_p should return a
- non-const pointer. The close operation would then explicitly signal, that the new value
- should be incorporated into the class. With our current implementation, the close member
- would be a no-op, however this ould free us from using the sockaddr values as a direct
- sotrage representation of the address.
+
+ This template provides an implementation template to implement generic addressing policy
+ classes which rely on the standard BSD socket API for their implementation
+ (connect/bind/getsockname/getpeername).
+
+ The \a Address template parameter specifies the address type of the addressing policy. This
+ type must have two members: \c sockaddr_p() and \c sockaddr_len(). The first must return a
+ <tt>struct sockaddr *</tt> to the address, the second must return the size of the address in
+ bytes. The pointer returned by \c sockaddr_p() must be non-const if called on a non-const
+ address. <em>The underlying socket address stored at that pointer might be
+ modified</em>.
+
+ This template class is inherited into addressing policy classes via private
+ inheritance. Then the members supported by the respective addressing policy are made
+ available via \c using declarations (See INet4AddressingPolicy for an Example).
+
+ \idea We could explicitly provide open_sockaddr_p() and close_sockaddr_p()
+ members. sockaddr_p could always return a const * whereas open_sockaddr_p should return a
+ non-const pointer. The close operation would then explicitly signal, that the new value
+ should be incorporated into the class. With our current implementation, the close member
+ would be a no-op, however this ould free us from using the sockaddr values as a direct
+ sotrage representation of the address.
*/
template <class Address>
struct GenericAddressingPolicy
typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0);
///< Return address of remote peer on connected sockets
/**< This member is only available if the socket handles
- communication policy is ConnectedCommunicationPolicy.
+ communication policy is ConnectedCommunicationPolicy.
- \param[in] handle socket handle to get peer address of
- \param[out] addr address of remote peer */
+ \param[in] handle socket handle to get peer address of
+ \param[out] addr address of remote peer */
static void local(FileHandle handle, Address & addr);
///< Return local of socket
/**< \param[in] handle socket handle to check
- \param[out] addr local socket address */
+ \param[out] addr local socket address */
template <class Policy>
static void connect(SocketHandle<Policy> handle, Address const & addr,
typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0);
///< Connect to remote host
/**< This member is only available if the socket handles
- communication policy is ConnectedCommunicationPolicy.
+ communication policy is ConnectedCommunicationPolicy.
- \param[in] handle socket handle
- \param[in] address address of remote peer to connect
- to */
+ \param[in] handle socket handle
+ \param[in] address address of remote peer to connect
+ to */
static void bind(FileHandle handle, Address const & addr);
///< Set local socket address
/**< \param[in] handle socket handle
- \param[in] addr local socket address */
+ \param[in] addr local socket address */
};
/// @}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-/** \file
+/** \file
\brief GenericSockAddr public header */
/** \defgroup addr_group Socket Addressing
-
+
To support the core socket functionality we need a collection of classing providing addressing
- for the different protocols.
+ for the different protocols.
Every Address Implementation used with the standard policy classes Has to have a set of minimum
members. These members are documented in GenericSockAddr. However, these members are \e neither
abstract \e nor virtual and other address classes do \e not inherit from GenericSockAddr. The
address classes are not usable polymorphically for performance reasons.
-
+
The interface defined above forces the implementation to be directly based on the corresponding
sockaddr data structures provided by the BSD socket API. These structures however are wrapped
into more flexible and more easy to use classes. Using the sockaddr representation increases the
/// @{
/** \brief Generic protocol-independant socket address
-
- This address type does not depend on the protocol of the socket. It does nowever not support
- any protocol specific API, so access to the address is very limited.
+
+ This address type does not depend on the protocol of the socket. It does nowever not support
+ any protocol specific API, so access to the address is very limited.
*/
class GenericSockAddr
{
public:
- GenericSockAddr();
+ GenericSockAddr();
- /// \name Generic Address Interface
- /// @{
+ /// \name Generic Address Interface
+ /// @{
- struct sockaddr * sockaddr_p(); ///< Return a pointer to sockaddr structure
+ struct sockaddr * sockaddr_p(); ///< Return a pointer to sockaddr structure
/**< The exact structure pointed to depends on the address
- family. The data pointed to must be \e mutable. The
- value must be changeable and any change of the value
- through this pointer must be reflected in the visible
- address interface.
- \returns non-const (!) pointer to sockaddr structure */
- struct sockaddr const * sockaddr_p() const; ///< Return a pointer to sockaddr structure
+ family. The data pointed to must be \e mutable. The
+ value must be changeable and any change of the value
+ through this pointer must be reflected in the visible
+ address interface.
+ \returns non-const (!) pointer to sockaddr structure */
+ struct sockaddr const * sockaddr_p() const; ///< Return a pointer to sockaddr structure
/**< This member is like sockaddr_p(), hoewever it does not
- allow changing the address.
- \returns const pointer to sockaddr structure */
- unsigned sockaddr_len() const; ///< Return size of address
+ allow changing the address.
+ \returns const pointer to sockaddr structure */
+ unsigned sockaddr_len() const; ///< Return size of address
/**< This meember return the size of the socket address
- structure as returned by sockaddr_p() in bytes.
- \returns size of respective sockaddr structure in bytes
- */
- /// @}
-
+ structure as returned by sockaddr_p() in bytes.
+ \returns size of respective sockaddr structure in bytes
+ */
+ /// @}
+
private:
- struct ::sockaddr_storage addr_;
+ struct ::sockaddr_storage addr_;
};
/// @}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
try {
// Replace lexical_cast with strtoul ?
addr_.sin_port = htons(boost::lexical_cast< ::u_int16_t >(std::string(address,i+1)));
- }
+ }
catch (boost::bad_lexical_cast const &) {
throw InvalidINetAddressException();
}
prefix_ senf::INet6Address::INet6Address(std::string const & addr)
{
if (inet_pton(AF_INET6,addr.c_str(),&addr_) <= 0)
- throw InvalidINetAddressException();
+ throw InvalidINetAddressException();
}
prefix_ senf::INet6Address::INet6Address(char const * addr)
{
if (inet_pton(AF_INET6,addr,&addr_) <= 0)
- throw InvalidINetAddressException();
+ throw InvalidINetAddressException();
}
prefix_ void senf::INet6Address::clear()
const
{
return ::memcmp(&sockaddr_.sin6_addr, &other.sockaddr_.sin6_addr, sizeof(sockaddr_.sin6_addr))==0 &&
- sockaddr_.sin6_port == other.sockaddr_.sin6_port &&
- sockaddr_.sin6_scope_id == other.sockaddr_.sin6_scope_id;
+ sockaddr_.sin6_port == other.sockaddr_.sin6_port &&
+ sockaddr_.sin6_scope_id == other.sockaddr_.sin6_scope_id;
}
prefix_ bool senf::INet6SocketAddress::operator!=(INet6SocketAddress const & other)
std::stringstream ss;
ss << '[' << host();
if (sockaddr_.sin6_scope_id != 0)
- ss << '@' << iface()
+ ss << '@' << iface()
<< "]:" << port();
return ss.str();
}
const
{
if (sockaddr_.sin6_scope_id == 0)
- return "";
+ return "";
char buffer[IFNAMSIZ];
BOOST_ASSERT( if_indextoname(sockaddr_.sin6_scope_id,buffer) );
return std::string(buffer);
typedef boost::tokenizer<separator> tokenizer;
// we don't add ':' to the list of separators since that would give as the IPv6 address
// as a list of tokens. We just strip the : from the port number manually
- separator sep ("", "@[]");
+ separator sep ("", "@[]");
tokenizer tokens (addr, sep);
tokenizer::iterator token (tokens.begin());
- if (token == tokens.end()
- || *token != "["
- || ++token == tokens.end()
- || inet_pton(AF_INET6, std::string(boost::begin(*token),boost::end(*token)).c_str(),
- &sockaddr_.sin6_addr) <= 0
- || ++token == tokens.end())
- throw InvalidINetAddressException();
+ if (token == tokens.end()
+ || *token != "["
+ || ++token == tokens.end()
+ || inet_pton(AF_INET6, std::string(boost::begin(*token),boost::end(*token)).c_str(),
+ &sockaddr_.sin6_addr) <= 0
+ || ++token == tokens.end())
+ throw InvalidINetAddressException();
if (*token == "@") {
- if (++token == tokens.end())
- throw InvalidINetAddressException();
- assignIface(std::string(boost::begin(*token),boost::end(*token)));
- if (++token == tokens.end()
- || *token != "]")
- throw InvalidINetAddressException();
+ if (++token == tokens.end())
+ throw InvalidINetAddressException();
+ assignIface(std::string(boost::begin(*token),boost::end(*token)));
+ if (++token == tokens.end()
+ || *token != "]")
+ throw InvalidINetAddressException();
} else if (*token != "]")
- throw InvalidINetAddressException();
+ throw InvalidINetAddressException();
if (++token == tokens.end()
- || *boost::begin(*token) != ':')
- throw InvalidINetAddressException();
+ || *boost::begin(*token) != ':')
+ throw InvalidINetAddressException();
try {
- sockaddr_.sin6_port = htons(
- boost::lexical_cast<unsigned>(std::string(boost::next(boost::begin(*token)),
- boost::end(*token))));
+ sockaddr_.sin6_port = htons(
+ boost::lexical_cast<unsigned>(std::string(boost::next(boost::begin(*token)),
+ boost::end(*token))));
} catch(boost::bad_lexical_cast const &) {
- throw InvalidINetAddressException();
+ throw InvalidINetAddressException();
}
if (++token != tokens.end())
- throw InvalidINetAddressException();
+ throw InvalidINetAddressException();
}
prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface)
{
if (iface.empty())
- sockaddr_.sin6_scope_id = 0;
+ sockaddr_.sin6_scope_id = 0;
else {
- sockaddr_.sin6_scope_id = if_nametoindex(iface.c_str());
- if (sockaddr_.sin6_scope_id == 0)
- throw InvalidINetAddressException();
+ sockaddr_.sin6_scope_id = if_nametoindex(iface.c_str());
+ if (sockaddr_.sin6_scope_id == 0)
+ throw InvalidINetAddressException();
}
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
prefix_ bool senf::INet4Address::operator==(INet4Address const & other)
const
{
- return addr_.sin_port == other.addr_.sin_port &&
+ return addr_.sin_port == other.addr_.sin_port &&
addr_.sin_addr.s_addr == other.addr_.sin_addr.s_addr;
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
unsigned char * p (&addr_.s6_addr[0]);
unsigned char * p_end (p+sizeof(addr_.s6_addr));
for (; p!=p_end && i!=i_end; ++p, ++i)
- *p = *i;
+ *p = *i;
if (p!=p_end || i!=i_end)
- throw InvalidINetAddressException();
+ throw InvalidINetAddressException();
}
///////////////////////////////ct.e////////////////////////////////////////
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief IPv4 socket address
- INet4Address wrapps the standard sockaddr_in datatype. It provides simple accessor methods
- to accss the host and port. It does \e not integrate \c gethostbyname or DNS lookup.
+ INet4Address wrapps the standard sockaddr_in datatype. It provides simple accessor methods
+ to accss the host and port. It does \e not integrate \c gethostbyname or DNS lookup.
- \todo Implement real INet4Address datatype and rename this one to INet4SockAddress ...
- \todo Implement more complete interface
- \todo gethostbyname support ?
+ \todo Implement real INet4Address datatype and rename this one to INet4SockAddress ...
+ \todo Implement more complete interface
+ \todo gethostbyname support ?
*/
class INet4Address
{
INet4Address();
INet4Address(char const * address); ///< Set address and port
/**< See INet4Address(std::string)
- \throws InvalidINetAddressException
- \fixme Why do I need this version? Shouldn't the
- std::string version be enough ? */
+ \throws InvalidINetAddressException
+ \fixme Why do I need this version? Shouldn't the
+ std::string version be enough ? */
INet4Address(std::string address); ///< Set address and port
/**< This constructor expects a string of the form
- 'xxx.xxx.xxx.xxx:pppp'. The constructor will use this
- value to initialize the host and port members. This
- constructor does \e only support numeric ip addresses
- not hostnames
- \param[in] address Address and port
- \throws InvalidINetAddressException */
+ 'xxx.xxx.xxx.xxx:pppp'. The constructor will use this
+ value to initialize the host and port members. This
+ constructor does \e only support numeric ip addresses
+ not hostnames
+ \param[in] address Address and port
+ \throws InvalidINetAddressException */
INet4Address(std::string host, unsigned port); ///< Set address and port explicitly
/**< \param[in] host ip address in dotted-quad notation
- \param[in] port port number
- \throws InvalidINetAddressException */
-
+ \param[in] port port number
+ \throws InvalidINetAddressException */
+
bool operator==(INet4Address const & other) const; ///< Check INet4Address for equality
void clear(); ///< Clear address/port to 0.0.0.0:0
- /// \name Generic Address Interface
- /// @{
+ /// \name Generic Address Interface
+ /// @{
struct sockaddr * sockaddr_p();
struct sockaddr const * sockaddr_p() const;
unsigned sockaddr_len() const;
- /// @}
+ /// @}
private:
void assignString(std::string addr);
-
+
struct ::sockaddr_in addr_;
};
/** \brief Write address and port to os
- \related INet4Address
+ \related INet4Address
*/
std::ostream & operator<<(std::ostream & os, INet4Address const & addr);
/** \brief IPv6 network address
- INet6Address represents a 128bit IPv6 network address. This class supports all standard
- numeric string representations of IPv6 addresses. This class does not integrate with \c
- gethostbyname() and so does not support host names.
+ INet6Address represents a 128bit IPv6 network address. This class supports all standard
+ numeric string representations of IPv6 addresses. This class does not integrate with \c
+ gethostbyname() and so does not support host names.
- The conversion constructors allow the use of string constants whereever an INet6Address is
- expected. Especially, it is possible to assign a string to an address to change it's value.
+ The conversion constructors allow the use of string constants whereever an INet6Address is
+ expected. Especially, it is possible to assign a string to an address to change it's value.
- \implementation The <tt>char const *</tt> constructor overload is needed to support
- string-literals where an INet6Address is expected (the C++ standard does not allow
- chaining conversion constructors like char const * -> std::string -» INet6Address)
+ \implementation The <tt>char const *</tt> constructor overload is needed to support
+ string-literals where an INet6Address is expected (the C++ standard does not allow
+ chaining conversion constructors like char const * -> std::string -> INet6Address)
*/
class INet6Address
{
INet6Address(); ///< Create empty address
INet6Address(std::string const & addr); ///< Create address from string representation
- INet6Address(char const * addr); ///< Create address from string representation
- INet6Address(struct in6_addr const & addr); ///< Create address from in6_addr
- template <class Range>
- explicit INet6Address(Range const & range); ///< Create address from arbitrary raw data
+ INet6Address(char const * addr); ///< Create address from string representation
+ INet6Address(struct in6_addr const & addr); ///< Create address from in6_addr
+ template <class Range>
+ explicit INet6Address(Range const & range); ///< Create address from arbitrary raw data
/**< This constructor will copy 16 bytes from the given
- range and interpret them as a IPv6 address in network
- byte order. This constructor is used to read an
- arbitrary address from it's binary representation.
+ range and interpret them as a IPv6 address in network
+ byte order. This constructor is used to read an
+ arbitrary address from it's binary representation.
- \param range arbitrary range, see <a
- href="http://www.boost.org/libs/range/index.html">Boost.Range</a>
- */
+ \param range arbitrary range, see <a
+ href="http://www.boost.org/libs/range/index.html">Boost.Range</a>
+ */
///@}
///////////////////////////////////////////////////////////////////////////
- void clear(); ///< Clear address
- std::string address() const; ///< Return printable address representation
+ void clear(); ///< Clear address
+ std::string address() const; ///< Return printable address representation
- bool operator==(INet6Address const & other) const; ///< Compare addresses for equality
- bool operator!=(INet6Address const & other) const; ///< Inverse of above
+ bool operator==(INet6Address const & other) const; ///< Compare addresses for equality
+ bool operator!=(INet6Address const & other) const; ///< Inverse of above
- struct in6_addr & addr(); ///< Access internal address representation
- struct in6_addr const & addr() const;
+ struct in6_addr & addr(); ///< Access internal address representation
+ struct in6_addr const & addr() const;
///< Access internal address representation in const context
- struct in6_addr * addr_p(); ///< Get pointer to internal address repr
- struct in6_addr const * addr_p() const;
+ struct in6_addr * addr_p(); ///< Get pointer to internal address repr
+ struct in6_addr const * addr_p() const;
///< Get const pointer to internal address repr
- unsigned addr_len() const; ///< Size of an IPv6 address (16 bytes)
+ unsigned addr_len() const; ///< Size of an IPv6 address (16 bytes)
protected:
private:
- struct in6_addr addr_;
+ struct in6_addr addr_;
};
-
+
/** \brief Output INet6Address instance as it's string representation
*/
std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
/** \brief IPv6 socket address
- This class wrapps the standard \c sockaddr_in6 structure. INet6SocketAddress provides access
- to all members of the sockaddr_in6 structure. Additionally, INet6SocketAddress supports the
- string representation
+ This class wrapps the standard \c sockaddr_in6 structure. INet6SocketAddress provides access
+ to all members of the sockaddr_in6 structure. Additionally, INet6SocketAddress supports the
+ string representation
- \par "" <tt>[</tt> <i>address</i> [ <tt>\@</tt> <i>interface</i> ] <tt>]:</tt> <i>port</i>
+ \par "" <tt>[</tt> <i>address</i> [ <tt>\@</tt> <i>interface</i> ] <tt>]:</tt> <i>port</i>
- Where \e address is an arbitrary numeric IPv6 address, \e interface is an optional network
- interface name and \e port is the port number. The interface specification is only valid if
- \e address is link-local address. The URL representation of an IPv6 address is as above
- without the optional interface spec.
+ Where \e address is an arbitrary numeric IPv6 address, \e interface is an optional network
+ interface name and \e port is the port number. The interface specification is only valid if
+ \e address is link-local address. The URL representation of an IPv6 address is as above
+ without the optional interface spec.
- INet6SocketAddress supports conversion constructors from it's string
- representation. Therefore, wherever a INet6SocketAddress instance is expected, a string may
- be used instead.
+ INet6SocketAddress supports conversion constructors from it's string
+ representation. Therefore, wherever a INet6SocketAddress instance is expected, a string may
+ be used instead.
- \implementation The sockaddr_in6 structure has an sin6_flowinfo member. However RFC3493 does
- not give the use of this field and specifies, that the field should be ignored ... so
- that's what we do. Furthermore, the GNU libc reference states, that this field is not
- implemented in the library.
+ \implementation The sockaddr_in6 structure has an sin6_flowinfo member. However RFC3493 does
+ not give the use of this field and specifies, that the field should be ignored ... so
+ that's what we do. Furthermore, the GNU libc reference states, that this field is not
+ implemented in the library.
- \implementation We need to return the address in host() by value since we need to return a
- INet6Address. However, sockaddr_in6 does not have one ...
+ \implementation We need to return the address in host() by value since we need to return a
+ INet6Address. However, sockaddr_in6 does not have one ...
- \implementation The <tt>char const *</tt> constructor overload is needed to support
- string-literals where an INet6SocketAddress is expected (the C++ standard does not allow
- chaining conversion constructors like <tt>char const *</tt> -> \c std::string -> \c
- INet6SocketAddress)
+ \implementation The <tt>char const *</tt> constructor overload is needed to support
+ string-literals where an INet6SocketAddress is expected (the C++ standard does not allow
+ chaining conversion constructors like <tt>char const *</tt> -> \c std::string -> \c
+ INet6SocketAddress)
- \idea Implement a INet6Address_ref class which has an interface identical to INet6Address
- and is convertible to INet6Address (the latter has a conversion constructor taking the
- former as arg). This class however references an external in6_addr instead of containing one
- itself. This can be used in INet6SocketAddress to increase the performance of some
- operations.
+ \idea Implement a INet6Address_ref class which has an interface identical to INet6Address
+ and is convertible to INet6Address (the latter has a conversion constructor taking the
+ former as arg). This class however references an external in6_addr instead of containing one
+ itself. This can be used in INet6SocketAddress to increase the performance of some
+ operations.
*/
class INet6SocketAddress
{
///@{
INet6SocketAddress(); ///< Create empty instance
- INet6SocketAddress(std::string const & addr);
+ INet6SocketAddress(std::string const & addr);
///< Initialize/convert from string represenation
INet6SocketAddress(char const * addr); ///< Same as above to support string literals
- INet6SocketAddress(INet6Address const & addr, unsigned port);
+ INet6SocketAddress(INet6Address const & addr, unsigned port);
///< Initialize from address and port
- INet6SocketAddress(INet6Address const & addr, unsigned port, std::string const & iface);
+ INet6SocketAddress(INet6Address const & addr, unsigned port, std::string const & iface);
///< Initialize explicitly from given parameters
- INet6SocketAddress(std::string const & addr, std::string const & iface);
+ INet6SocketAddress(std::string const & addr, std::string const & iface);
///< Initialize from URL representation and explit interface
///@}
///////////////////////////////////////////////////////////////////////////
- bool operator==(INet6SocketAddress const & other) const; ///< Check addresses for equality
- bool operator!=(INet6SocketAddress const & other) const; ///< Inverse of above
+ bool operator==(INet6SocketAddress const & other) const; ///< Check addresses for equality
+ bool operator!=(INet6SocketAddress const & other) const; ///< Inverse of above
+
+ void clear(); ///< Clear socket address
- void clear(); ///< Clear socket address
+ std::string address() const; ///< Get printable address representation
- std::string address() const; ///< Get printable address representation
+ INet6Address host() const; ///< Get address
+ void host(INet6Address const & addr); ///< Change address
+
+ unsigned port() const; ///< Get port number
+ void port(unsigned poirt); ///< Change port number
+
+ std::string iface() const; ///< Get interface name
+ void iface(std::string const & iface); ///< Change interface
- INet6Address host() const; ///< Get address
- void host(INet6Address const & addr); ///< Change address
-
- unsigned port() const; ///< Get port number
- void port(unsigned poirt); ///< Change port number
-
- std::string iface() const; ///< Get interface name
- void iface(std::string const & iface); ///< Change interface
-
///\name Generic SocketAddress interface
///@{
protected:
private:
- void assignAddr(std::string const & addr);
- void assignIface(std::string const & iface);
+ void assignAddr(std::string const & addr);
+ void assignIface(std::string const & iface);
- struct sockaddr_in6 sockaddr_;
+ struct sockaddr_in6 sockaddr_;
};
/** \brief Output INet6SocketAddress instance as it's string representation
/** \brief Signal invalid INet address syntax
- \related INet4Address
- \relatesalso INet6Address
+ \related INet4Address
+ \relatesalso INet6Address
*/
struct InvalidINetAddressException : public std::exception
{ char const * what() const throw() { return "invalid inet address"; } };
/// @{
/** \brief Addressing policy supporting IPv4 addressing
-
- \par Address Type:
- INet4Address
-
- This addressing policy implements addressing using Internet V4
- addresses.
-
- The various members are directly importet from
- GenericAddressingPolicy which see for a detailed
- documentation.
+
+ \par Address Type:
+ INet4Address
+
+ This addressing policy implements addressing using Internet V4
+ addresses.
+
+ The various members are directly importet from
+ GenericAddressingPolicy which see for a detailed
+ documentation.
*/
- struct INet4AddressingPolicy
+ struct INet4AddressingPolicy
: public AddressingPolicyBase,
private GenericAddressingPolicy<INet4Address>
{
};
/** \brief Addressing policy supporting IPv6 addressing
-
- \par Address Type:
- INet6SocketAddress
-
- This addressing policy implements addressing using Internet V6
- addresses.
-
- The various members are directly importet from
- GenericAddressingPolicy which see for a detailed
- documentation.
+
+ \par Address Type:
+ INet6SocketAddress
+
+ This addressing policy implements addressing using Internet V6
+ addresses.
+
+ The various members are directly importet from
+ GenericAddressingPolicy which see for a detailed
+ documentation.
*/
struct INet6AddressingPolicy
: public AddressingPolicyBase,
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
{
INet4Address addr;
-
+
addr = "127.0.0.1:12345";
}
-
+
{
INet4Address addr1("127.0.0.1:12345");
INet4Address addr2(std::string("127.0.0.1:12345"));
using senf::InvalidINetAddressException;
{
- INet6Address addr1 ("0102:0304:0506:0708:090A:0B0C:0D0E:0F00");
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[0], 1 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[1], 2 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[2], 3 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[3], 4 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[4], 5 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[5], 6 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[6], 7 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[7], 8 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[8], 9 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[9], 10 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[10], 11 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[11], 12 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[12], 13 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[13], 14 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[14], 15 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[15], 0 );
- INet6Address addr2;
- BOOST_CHECK_EQUAL( addr2, "::" );
- addr2 = "::1";
- BOOST_CHECK( addr1 != addr2 );
- addr1 ="::1";
- BOOST_CHECK_EQUAL( addr1, addr2 );
- BOOST_CHECK_EQUAL( addr1.address(),"::1" );
- addr1.clear();
- addr2 = "::";
- BOOST_CHECK_EQUAL( addr1, addr2 );
- BOOST_CHECK_THROW( addr1 = "", InvalidINetAddressException );
- BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr1), "::" );
- unsigned char data[] = { 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x21, 0 };
- INet6Address addr3 (std::make_pair(&data[0],&data[0]+sizeof(data)-1));
- BOOST_CHECK_EQUAL( addr3, "1200::21" );
- BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data))),
- InvalidINetAddressException );
- BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data)-2)),
- InvalidINetAddressException );
+ INet6Address addr1 ("0102:0304:0506:0708:090A:0B0C:0D0E:0F00");
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[0], 1 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[1], 2 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[2], 3 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[3], 4 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[4], 5 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[5], 6 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[6], 7 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[7], 8 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[8], 9 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[9], 10 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[10], 11 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[11], 12 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[12], 13 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[13], 14 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[14], 15 );
+ BOOST_CHECK_EQUAL( addr1.addr().s6_addr[15], 0 );
+ INet6Address addr2;
+ BOOST_CHECK_EQUAL( addr2, "::" );
+ addr2 = "::1";
+ BOOST_CHECK( addr1 != addr2 );
+ addr1 ="::1";
+ BOOST_CHECK_EQUAL( addr1, addr2 );
+ BOOST_CHECK_EQUAL( addr1.address(),"::1" );
+ addr1.clear();
+ addr2 = "::";
+ BOOST_CHECK_EQUAL( addr1, addr2 );
+ BOOST_CHECK_THROW( addr1 = "", InvalidINetAddressException );
+ BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr1), "::" );
+ unsigned char data[] = { 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x21, 0 };
+ INet6Address addr3 (std::make_pair(&data[0],&data[0]+sizeof(data)-1));
+ BOOST_CHECK_EQUAL( addr3, "1200::21" );
+ BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data))),
+ InvalidINetAddressException );
+ BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data)-2)),
+ InvalidINetAddressException );
}
{
- INet6SocketAddress addr;
- BOOST_CHECK_EQUAL( addr.host(), "::" );
- BOOST_CHECK_EQUAL( addr.port(), 0u );
- BOOST_CHECK_EQUAL( addr.iface(), "" );
- addr = "[12::21]:12345";
- BOOST_CHECK_EQUAL( addr.host(), "12::21" );
- BOOST_CHECK_EQUAL( addr.port(), 12345u );
- BOOST_CHECK_EQUAL( addr.iface(), "" );
- BOOST_CHECK_EQUAL( addr, INet6SocketAddress("[12::21]:12345") );
+ INet6SocketAddress addr;
+ BOOST_CHECK_EQUAL( addr.host(), "::" );
+ BOOST_CHECK_EQUAL( addr.port(), 0u );
+ BOOST_CHECK_EQUAL( addr.iface(), "" );
+ addr = "[12::21]:12345";
+ BOOST_CHECK_EQUAL( addr.host(), "12::21" );
+ BOOST_CHECK_EQUAL( addr.port(), 12345u );
+ BOOST_CHECK_EQUAL( addr.iface(), "" );
+ BOOST_CHECK_EQUAL( addr, INet6SocketAddress("[12::21]:12345") );
}
-
+
{
- INet6SocketAddress addr ("::1", 1);
- BOOST_CHECK_EQUAL( addr, "[::1]:1" );
- BOOST_CHECK_EQUAL( addr.iface(), "" );
+ INet6SocketAddress addr ("::1", 1);
+ BOOST_CHECK_EQUAL( addr, "[::1]:1" );
+ BOOST_CHECK_EQUAL( addr.iface(), "" );
}
{
- INet6SocketAddress addr ("::1", 1, "lo");
- BOOST_CHECK_EQUAL( addr, "[::1@lo]:1" );
- BOOST_CHECK_EQUAL( addr.iface(), "lo" );
- addr.iface("");
- BOOST_CHECK_EQUAL( addr.iface(), "" );
- addr.port(100u);
- BOOST_CHECK_EQUAL( addr.port(), 100u );
- addr.host("::2");
- BOOST_CHECK_EQUAL( addr.host(), "::2" );
- BOOST_CHECK_THROW( addr = "", InvalidINetAddressException );
- BOOST_CHECK_THROW( addr = "[::1]", InvalidINetAddressException );
- BOOST_CHECK_THROW( addr = "[::1]1234", InvalidINetAddressException );
- addr = "[12::21@lo]:12345";
- BOOST_CHECK_EQUAL( addr.address(), "[12::21@lo]:12345" );
- BOOST_CHECK_EQUAL( addr.host(), "12::21" );
- BOOST_CHECK_EQUAL( addr.port(), 12345u );
- BOOST_CHECK_EQUAL( addr.iface(), "lo" );
- BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr), "[12::21@lo]:12345" );
+ INet6SocketAddress addr ("::1", 1, "lo");
+ BOOST_CHECK_EQUAL( addr, "[::1@lo]:1" );
+ BOOST_CHECK_EQUAL( addr.iface(), "lo" );
+ addr.iface("");
+ BOOST_CHECK_EQUAL( addr.iface(), "" );
+ addr.port(100u);
+ BOOST_CHECK_EQUAL( addr.port(), 100u );
+ addr.host("::2");
+ BOOST_CHECK_EQUAL( addr.host(), "::2" );
+ BOOST_CHECK_THROW( addr = "", InvalidINetAddressException );
+ BOOST_CHECK_THROW( addr = "[::1]", InvalidINetAddressException );
+ BOOST_CHECK_THROW( addr = "[::1]1234", InvalidINetAddressException );
+ addr = "[12::21@lo]:12345";
+ BOOST_CHECK_EQUAL( addr.address(), "[12::21@lo]:12345" );
+ BOOST_CHECK_EQUAL( addr.host(), "12::21" );
+ BOOST_CHECK_EQUAL( addr.port(), 12345u );
+ BOOST_CHECK_EQUAL( addr.iface(), "lo" );
+ BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr), "[12::21@lo]:12345" );
}
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \file
\brief IPv[46]Protocol public header
- \todo what about OOB data?
+ \todo what about OOB data?
\todo Implement IP_RECVERR / MSG_ERRQUEUE. This should be placed
into an additional protocol facet since IP_RECVERR is only valid
/// @{
/** \brief Protocol facet providing IPv4 Addressing related API
-
- This protocol facet introduces all the socket api protocol members which are related to IPv4
- addressing.
- \todo Is it safe, not to allow setting the interface index on add/drop? what does it do
- (especially if the local addres is given ?). What have I been thinking here ???
-
- \todo move all multicast-methods into an extra IPv4MulticastProtocol class (it's only
- available on datagram sockets)
+ This protocol facet introduces all the socket api protocol members which are related to IPv4
+ addressing.
- \todo the multicast add/remove/iface semantics are quite unclear ...
+ \todo Is it safe, not to allow setting the interface index on add/drop? what does it do
+ (especially if the local addres is given ?). What have I been thinking here ???
- \todo connect() is only available on stream sockets. We want to access bind() and connet()
- via the ClientSocketHandle -> see SocketProtocol todo point
+ \todo move all multicast-methods into an extra IPv4MulticastProtocol class (it's only
+ available on datagram sockets)
+
+ \todo the multicast add/remove/iface semantics are quite unclear ...
+
+ \todo connect() is only available on stream sockets. We want to access bind() and connet()
+ via the ClientSocketHandle -> see SocketProtocol todo point
*/
- class IPv4Protocol
+ class IPv4Protocol
: public virtual SocketProtocol
{
public:
void connect(INet4Address const & address) const; ///< Connect to remote address
/**< \todo make this obsolete by allowing access to the
- ClientSocketHandle from ConcreateSocketProtocol
- \param[in] address Address to connect to */
+ ClientSocketHandle from ConcreateSocketProtocol
+ \param[in] address Address to connect to */
void bind(INet4Address const & address) const; ///< Set local socket address
/**< \todo make this obsolete by allowing access to the
- ClientSocketHandle from ConcreateSocketProtocol
- \param[in] address Address to set */
+ ClientSocketHandle from ConcreateSocketProtocol
+ \param[in] address Address to set */
unsigned mcTTL() const; ///< Return current multicast TTL
void mcTTL(unsigned value) const; ///< Set multicast TTL
void mcAddMembership(INet4Address const & mcAddr) const;
///< Join multicast group
/**< This member will add \a mcAddr to the list of multicast
- groups received. The group is joined on the default
- interface.
- \param[in] mcAddr address of group to join
- \todo fix this as soon as we have a real address class
- (differend from the sockaddress class */
+ groups received. The group is joined on the default
+ interface.
+ \param[in] mcAddr address of group to join
+ \todo fix this as soon as we have a real address class
+ (differend from the sockaddress class */
void mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr) const;
///< join multicast group on a specific address/interface
/**< This member will add \a mcAddr to the list of multicast
- groups received. The group is joined on the interface
- with the given local address.
- \param[in] mcAddr address of group to join
- \param[in] localAddr address of interface to join on
- \todo fix this as soon as we have a real address class
- (differend from the sockaddress class */
+ groups received. The group is joined on the interface
+ with the given local address.
+ \param[in] mcAddr address of group to join
+ \param[in] localAddr address of interface to join on
+ \todo fix this as soon as we have a real address class
+ (differend from the sockaddress class */
void mcDropMembership(INet4Address const & mcAddr) const;
- ///< Leave multicast group
+ ///< Leave multicast group
/**< This member will remove \a mcAddr from the list of
- multicast groups received. The group is left from the
- default interface.
- \param[in] mcAddr address of group to leave
- \todo fix this as soon as we have a real address class
- (differend from the sockaddress class */
+ multicast groups received. The group is left from the
+ default interface.
+ \param[in] mcAddr address of group to leave
+ \todo fix this as soon as we have a real address class
+ (differend from the sockaddress class */
void mcDropMembership(INet4Address const & mcAddr, INet4Address const & localAddr) const;
///< leave multicast group on a specific address/interface
/**< This member will remove \a mcAddr from the list of
- multicast groups received. The group is left from the
- interface with the given local address.
- \param[in] mcAddr address of group to leave
- \param[in] localAddr address of interface to leave from
- \todo fix this as soon as we have a real address class
- (differend from the sockaddress class */
+ multicast groups received. The group is left from the
+ interface with the given local address.
+ \param[in] mcAddr address of group to leave
+ \param[in] localAddr address of interface to leave from
+ \todo fix this as soon as we have a real address class
+ (differend from the sockaddress class */
void mcIface(std::string iface = std::string()) const;
///< set default multicast interface of the socket
/**< \param[in] iface name of interface */
};
-
+
/** \brief Protocol facet providing IPv6 Addressing related API
-
- This protocol facet introduces all the socket api protocol members which are related to IPv6
- addressing.
+
+ This protocol facet introduces all the socket api protocol members which are related to IPv6
+ addressing.
*/
class IPv6Protocol
: public virtual SocketProtocol
public:
void connect(INet6SocketAddress const & address) const; ///< Connect to remote address
/**< \todo make this obsolete by allowing access to the
- ClientSocketHandle from ConcreateSocketProtocol
- \param[in] address Address to connect to */
+ ClientSocketHandle from ConcreateSocketProtocol
+ \param[in] address Address to connect to */
void bind(INet6SocketAddress const & address) const; ///< Set local socket address
/**< \todo make this obsolete by allowing access to the
- ClientSocketHandle from ConcreateSocketProtocol
- \param[in] address Address to set */
+ ClientSocketHandle from ConcreateSocketProtocol
+ \param[in] address Address to set */
};
/// @}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
if (addr_.sll_halen == 0)
return std::string();
std::stringstream s;
-
+
unsigned char const * i = &addr_.sll_addr[0];
while (1) {
s << std::hex << std::setw(2) << std::setfill('0') << unsigned(*i);
prefix_ senf::detail::LLAddressFromStringRange
senf::llAddress(std::string address)
{
- detail::StringSplitIterator i =
+ detail::StringSplitIterator i =
boost::make_split_iterator(address, boost::token_finder(boost::is_any_of("-: ")));
detail::StringSplitIterator i_end;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
const
{
/** \todo make sure, that the value really is in network byte
- order */
+ order */
return ntohs(addr_.sll_hatype);
}
const
{
/** \todo make sure, that the value really is in network byte
- order */
+ order */
return ntohs(addr_.sll_pkttype);
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief Link local address
- LLSocketAddress wrapps the standard sockaddr_ll datatype.
-
- \todo I don't think the current implementation is
- sensible. I'll have to reimplement this class probably
- from scratch.
-
- \implementation The class relies uses a very flexible
- 'ForwardRange' representation for a raw ll
- address (See <a
- href="http://www.boost.org/libs/range/index.html">Boost.Range</a>).
- This representation allows zero-copy imlementations of
- many operations, however it is probably not worth the
- effort since the ll address is restricted to a max of 8
- bytes. Therefore this will be changed and the concrete
- implementation is not documented very well ...
+ LLSocketAddress wrapps the standard sockaddr_ll datatype.
+
+ \todo I don't think the current implementation is
+ sensible. I'll have to reimplement this class probably
+ from scratch.
+
+ \implementation The class relies uses a very flexible
+ 'ForwardRange' representation for a raw ll
+ address (See <a
+ href="http://www.boost.org/libs/range/index.html">Boost.Range</a>).
+ This representation allows zero-copy imlementations of
+ many operations, however it is probably not worth the
+ effort since the ll address is restricted to a max of 8
+ bytes. Therefore this will be changed and the concrete
+ implementation is not documented very well ...
*/
class LLSocketAddress
{
// I'll leave it as it is ...
typedef boost::iterator_range<unsigned char const *> LLAddress;
-
+
LLSocketAddress();
// And this is for bind
explicit LLSocketAddress(unsigned protocol, std::string interface="");
};
/** \brief
- \related LLSocketAddress
+ \related LLSocketAddress
*/
detail::LLAddressFromStringRange llAddress(std::string address);
// except for academic cases
// STOP: ... how about std::vector<...>::iterator ?? isn't that a ..pointer ?
/** \brief Convert raw link-local address into printable form
- \related LLSocketAddress
+ \related LLSocketAddress
*/
template <class ForwardRange>
std::string llAddress(ForwardRange const & address,
typename boost::enable_if< boost::is_class<ForwardRange> >::type * = 0);
/** \brief Signal invalid link local address syntax
- \related LLSocketAddress
+ \related LLSocketAddress
*/
struct InvalidLLSocketAddressException : public std::exception
{ char const * what() const throw() { return "invalid ll address"; } };
/** \brief Addressing policy supporting link-local addressing
- \par Address Type:
- LLSocketAddress
-
- This addressing policy implements generic link local
- addressing. The predominant type of link local addressing is
- Ethernet addressing.
+ \par Address Type:
+ LLSocketAddress
+
+ This addressing policy implements generic link local
+ addressing. The predominant type of link local addressing is
+ Ethernet addressing.
- Since the link layer does not support the notion of
- connections, link local addresses do not support the connect()
- or peer() members.
+ Since the link layer does not support the notion of
+ connections, link local addresses do not support the connect()
+ or peer() members.
*/
struct LLAddressingPolicy
: public AddressingPolicyBase,
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace detail {
/** \brief Convert two-char hexbyte representation to numeric value
- \internal
+ \internal
*/
struct HexConverter {
typedef unsigned char result_type;
typedef boost::iterator_range<HexSplitIterator> LLAddressFromStringRange;
/** \brief convert single hex digit to numeric value
- \internal
+ \internal
*/
unsigned char hexnibble(char c);
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
BOOST_AUTO_UNIT_TEST(llAddress)
{
- {
+ {
senf::LLSocketAddress a;
BOOST_CHECK_EQUAL( a.protocol(), 0u );
a.protocol(123);
BOOST_CHECK_EQUAL( a.protocol(), 123u );
}
-
+
{
senf::LLSocketAddress a (
senf::llAddress("11-12-13-14-15-16"), "lo");
-
+
BOOST_CHECK_EQUAL( a.protocol(), 0u );
BOOST_CHECK_EQUAL( a.interface(), "lo" );
BOOST_CHECK_EQUAL( a.arptype(), 0u );
{
senf::LLSocketAddress a (123, "lo");
-
+
BOOST_CHECK_EQUAL( a.protocol(), 123u );
BOOST_CHECK_EQUAL( a.interface(), "lo" );
BOOST_CHECK_EQUAL( a.arptype(), 0u );
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
several concepts:
\li The basic visible interface is a \link handle_group handle
- object \endlink
+ object \endlink
\li The socket interface relies on a \link policy_group policy
- framework \endlink to configure it's functionality
+ framework \endlink to configure it's functionality
\li The rest of the socket API is accessible using a classic
- inheritance hierarchy of \link protocol_group protocol classes
- \endlink
+ inheritance hierarchy of \link protocol_group protocol classes
+ \endlink
The handle/body architecture provides automatic reference counted
management of socket instances, the policy framework provides
\ref handle_group \n
\ref policy_group \n
\ref protocol_group \n
- \ref extend \n
+ \ref extend \n
\ref implementation
*/
\code
typedef ClientSocketHandle<
- MakeSocketPolicy<
- ReadablePolicy,
+ MakeSocketPolicy<
+ ReadablePolicy,
StreamFramingPolicy,
ConnectedCommunicationPolicy > > MyReadableHandle;
-
+
\endcode
This defines \c MyReadableHandle as a ClientSocketHandle
ConnectedCommunicationPolicy does not have a \c readfrom
member.
*/
-
+
/** \page extend Extending the Library
-
+
There are two layers, on which the socket library can be
extended: On the protocol layer and on the policy layer. Extending
the protocol layer is quite simple and works as long as the
very complicated however the integration is more complex.
\section extend_protocol Writing a new protocol class
-
+
Most protocols can be implemented by just implementing a new
protocol class. The protocol class must be derived from
ConcreteSocketProtocol and takes the socket policy (as
aware of some important limitations of the socket library:
\li When you define a new policy for some axis, this new policy
- <em>must not</em> be derived from one of the existing concrete
- policy classes (except of course the respective policy axis
- base class). This is important since the policy type is \e not
- polymorphic. The policy to be used is selected by the compiler
- using the \e static type, which is exactly what is desired,
- since this allows calls to be efficiently inlined.
+ <em>must not</em> be derived from one of the existing concrete
+ policy classes (except of course the respective policy axis
+ base class). This is important since the policy type is \e not
+ polymorphic. The policy to be used is selected by the compiler
+ using the \e static type, which is exactly what is desired,
+ since this allows calls to be efficiently inlined.
\li Therefore, extending the policy framework will make the new
- socket probably \e incompatible with generic code which relies
- on the policy axis which is extended. Example: If you write a
- new write policy because your protocol does not use ordinary
- write() system calls but some protocol specific API, Then any
- generic function relying on WritablePolicy will \e not
- work with the new socket, since the socket does \e not have
- this policy, it has some other kind of write policy.
+ socket probably \e incompatible with generic code which relies
+ on the policy axis which is extended. Example: If you write a
+ new write policy because your protocol does not use ordinary
+ write() system calls but some protocol specific API, Then any
+ generic function relying on WritablePolicy will \e not
+ work with the new socket, since the socket does \e not have
+ this policy, it has some other kind of write policy.
Therefore you need to be careful of what you are doing. The first
step is to find out, which policy you will have to implement. For
<tr><td>policy interface</td> <td>interface directly provided by
ClientSocketHandle/ServerSocketHandle and defined through the
policy</td>
-
+
<tr><td>protocol interface</td> <td>interface provided by the
protocol class and accessible via the
ProtocolClientSocketHandle::protocol()/ProtocolServerSocketHandle::protocol()
*/
/** \page implementation Implementation notes
-
+
\section class_diagram Class Diagram
\image html SocketLibrary-classes.png
\section impl_notes Arbitrary Implementation Notes
\li The implementation tries to isolate the library user as much
- as possible from the system header files since those headers
- define a lot of define symbols and introduce a host of symbols
- into the global namespace. This is, why some classes define
- their own \c enum types to replace system defined define
- constants. This also precludes inlining some functionality.
+ as possible from the system header files since those headers
+ define a lot of define symbols and introduce a host of symbols
+ into the global namespace. This is, why some classes define
+ their own \c enum types to replace system defined define
+ constants. This also precludes inlining some functionality.
\li To reduce overhead, template functions/members which are
- more than one-liners are often implemented in terms of a
- non-template function/member. This is also used to further the
- isolation from system headers as defined above (template code
- must always be included into every compilation unit together
- with all headers need for the implementation).
+ more than one-liners are often implemented in terms of a
+ non-template function/member. This is also used to further the
+ isolation from system headers as defined above (template code
+ must always be included into every compilation unit together
+ with all headers need for the implementation).
*/
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// mode: flyspell
// mode: auto-fill
-// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
{
/** \bug There are some failures here ... need to investigate */
- // The interface is really stupid: as far as i understand, it is possible to
+ // The interface is really stupid: as far as i understand, it is possible to
// enable PROMISC and ALLMULTI seperately, however PROMISC is really a superset
// of ALLMULTI ... grmpf ... therefore we allways set/reset both to implement sane
// semantics
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
template <class ForwardRange>
prefix_ senf::detail::Range_LLAddressCopier<ForwardRange>::
Range_LLAddressCopier(ForwardRange const & range)
- : range_ (range)
+ : range_ (range)
{}
template <class ForwardRange>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/// \addtogroup concrete_protocol_group
/// @{
-
+
typedef MakeSocketPolicy<
LLAddressingPolicy,
DatagramFramingPolicy,
>::policy Packet_Policy; ///< Policy of PacketProtocol
/** \brief Raw Packet-Socket access (Linux)
-
- \par Socket Handle typedefs:
- \ref PacketSocketHandle (ProtocolClientSocketHandle)
- \par Protocol Interface:
- ClientSocketHandle::read(), ClientSocketHandle::readfrom(), ClientSocketHandle::writeto(),
- ClientSocketHandle::bind(), ClientSocketHandle::local(), ClientSocketHandle::rcvbuf(),
- ClientSocketHandle::sndbuf()
+ \par Socket Handle typedefs:
+ \ref PacketSocketHandle (ProtocolClientSocketHandle)
+
+ \par Protocol Interface:
+ ClientSocketHandle::read(), ClientSocketHandle::readfrom(), ClientSocketHandle::writeto(),
+ ClientSocketHandle::bind(), ClientSocketHandle::local(), ClientSocketHandle::rcvbuf(),
+ ClientSocketHandle::sndbuf()
- \par Address Type:
- LLSocketAddress
+ \par Address Type:
+ LLSocketAddress
- The PacketProtocol provides access to the linux packet socket API. This API gives access to
- the low level network packets. The packet socket allows read() and write() operations. The
- PacketProtocol has no concept of a server socket.
+ The PacketProtocol provides access to the linux packet socket API. This API gives access to
+ the low level network packets. The packet socket allows read() and write() operations. The
+ PacketProtocol has no concept of a server socket.
- This class is utilized as the protocol class of the ProtocolClientSocketHandle via the
- Socket Handle typedefs above.
+ This class is utilized as the protocol class of the ProtocolClientSocketHandle via the
+ Socket Handle typedefs above.
*/
- class PacketProtocol
+ class PacketProtocol
: public ConcreteSocketProtocol<Packet_Policy>,
public BSDSocketProtocol
{
enum PromiscMode { Promiscuous, AllMulticast, None };
///< Interface modes
- ///\name Constructors
- ///@{
+ ///\name Constructors
+ ///@{
void init_client(SocketType type = RawSocket, int protocol = -1) const;
///< Create packet socket
/**< The new socket will receive all packets of the given
- IEEE 802.3 \a protocol. The socket will receive all
- packets, if \a protocol is -1.
-
- If \a type is \c RawSocket, the packet will include the
- link-level header (the Ethernet header). Sent packets
- must already include a well formed ll header.
-
- If \a type is \c DatagramSocket, the link level header
- will not be part of the packet data. The ll header will
- be removed from received packets and a correct ll
- header will be created on sent packets.
-
- \param[in] type socket type
- \param[in] protocol IEEE 802.3 protocol number */
- /**< \note This member is implicitly called from the
- ProtocolClientSocketHandle::ProtocolClientSocketHandle()
- constructor */
- ///@}
-
- ///\name Protocol Interface
- ///@{
- void promisc(std::string interface, PromiscMode mode) const;
+ IEEE 802.3 \a protocol. The socket will receive all
+ packets, if \a protocol is -1.
+
+ If \a type is \c RawSocket, the packet will include the
+ link-level header (the Ethernet header). Sent packets
+ must already include a well formed ll header.
+
+ If \a type is \c DatagramSocket, the link level header
+ will not be part of the packet data. The ll header will
+ be removed from received packets and a correct ll
+ header will be created on sent packets.
+
+ \param[in] type socket type
+ \param[in] protocol IEEE 802.3 protocol number */
+ /**< \note This member is implicitly called from the
+ ProtocolClientSocketHandle::ProtocolClientSocketHandle()
+ constructor */
+ ///@}
+
+ ///\name Protocol Interface
+ ///@{
+ void promisc(std::string interface, PromiscMode mode) const;
///< Change interface mode
/**< This member will change the reception on the given
- interface. The modes available are
+ interface. The modes available are
- <dl>
- <dt>\e None</dt><dd>No special mode set. Only receive
- packets addressed to the interface or of joined
- multicast groups</dd>
- <dt>\e AllMulticast</dt><dd>Additionally receive all
- multicast traffic</dd>
- <dt>\e Promiscuous</dt><dd>Receive all packets on the
- wire</dd>
- </dl>
+ <dl>
+ <dt>\e None</dt><dd>No special mode set. Only receive
+ packets addressed to the interface or of joined
+ multicast groups</dd>
+ <dt>\e AllMulticast</dt><dd>Additionally receive all
+ multicast traffic</dd>
+ <dt>\e Promiscuous</dt><dd>Receive all packets on the
+ wire</dd>
+ </dl>
- \param[in] interface interface to modify
- \param[in] mode new interface mode */
+ \param[in] interface interface to modify
+ \param[in] mode new interface mode */
// See LLSocketAddress for a discussion/rationale for ForwardRange here
template <class ForwardRange>
void mcAdd(std::string interface, ForwardRange const & address) const;
///< Enable reception of a multicast group
/**< mcAdd will join a new multicast group. The address
- parameter is specified as an arbitrary forward range
- (see <a
- href="http://www.boost.org/libs/range/index.html">Boost.Range</a>)
- of up to 8 bytes. This allows to initialize the
- address from an arbitrary sources without excessive
- copying.
-
- \param[in] interface interface with which to join
- \param[in] address multicast address to join
-
- \see \ref LLSocketAddress */
- template <class ForwardRange>
+ parameter is specified as an arbitrary forward range
+ (see <a
+ href="http://www.boost.org/libs/range/index.html">Boost.Range</a>)
+ of up to 8 bytes. This allows to initialize the
+ address from an arbitrary sources without excessive
+ copying.
+
+ \param[in] interface interface with which to join
+ \param[in] address multicast address to join
+
+ \see \ref LLSocketAddress */
+ template <class ForwardRange>
void mcDrop(std::string interface, ForwardRange const & address) const;
///< Disable reception of a multicast group
/**< \see \ref mcAdd() */
- ///@}
+ ///@}
- ///\name Abstract Interface Implementation
- ///@{
+ ///\name Abstract Interface Implementation
+ ///@{
std::auto_ptr<SocketProtocol> clone() const;
unsigned available() const;
bool eof() const;
- ///@}
+ ///@}
private:
template<class ForwardRange>
typedef ProtocolClientSocketHandle<PacketProtocol> PacketSocketHandle;
///< SocketHandle of the PacketProtocol
/**< \related PacketPrototol */
-
+
/// @}
}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace detail {
/** \brief Abstract address copier
- \internal
-
- This class provides the abstract interface to copy a
- link-local address to a destination address.
+ \internal
+
+ This class provides the abstract interface to copy a
+ link-local address to a destination address.
*/
struct LLAddressCopier
{
};
/** \brief Implementation of LLAddressCopier to copy arbitrary Range
- \internal
+ \internal
- This implementation of the LLAddressCopier interface will copy
- an arbitrary range to the target address. This class is used,
- to convert the compile-time polymorphism of templates
- (provided by the \c ForwardRange template argument) into
- runtime polymorphism (provided by the abstract LLAddressCopier
- interface).
+ This implementation of the LLAddressCopier interface will copy
+ an arbitrary range to the target address. This class is used,
+ to convert the compile-time polymorphism of templates
+ (provided by the \c ForwardRange template argument) into
+ runtime polymorphism (provided by the abstract LLAddressCopier
+ interface).
*/
template <class ForwardRange>
struct Range_LLAddressCopier
: public LLAddressCopier
{
Range_LLAddressCopier(ForwardRange const & range);
-
+
unsigned operator()(unsigned char * target) const;
ForwardRange const & range_;
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
{
senf::PacketSocketHandle sock;
-
+
BOOST_CHECK_NO_THROW( sock.bind(senf::LLSocketAddress("lo")) );
senf::LLSocketAddress a;
BOOST_CHECK_NO_THROW( sock.local(a) );
BOOST_CHECK_EQUAL( a.interface(), "lo" );
// How am I supposed to test read and write .. grmpf ..
-
- /*
+
+ /*
BOOST_CHECK_NO_THROW( sock.protocol().promisc(
"lo",senf::PacketProtocol::Promiscuous) );
BOOST_CHECK_NO_THROW( sock.protocol().promisc(
BOOST_CHECK_NO_THROW( sock.protocol().promisc(
"lo",senf::PacketProtocol::None) );
*/
-
+
BOOST_CHECK_NO_THROW( sock.protocol().mcAdd(
"lo",senf::llAddress("01-02-03-04-05-06")) );
BOOST_CHECK_NO_THROW( sock.protocol().mcDrop(
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-/** \file
+/** \file
\brief ProtocolClientSocketHandle inline template
- implementation
+ implementation
*/
// Definition of inline template functions
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief Protocol specific socket handle (client interface)
- The ProtocolClientSocketHandle is the client interface leaf class of the handle
- hierarchy. This is the class to instantiate to open a new socket. This is also the \e only
- class, which can be used to open a client socket.
+ The ProtocolClientSocketHandle is the client interface leaf class of the handle
+ hierarchy. This is the class to instantiate to open a new socket. This is also the \e only
+ class, which can be used to open a client socket.
- The \a Protocol template argument defines the protocol of the socket. This protocol provides
- the protocol interface of the socket as well as the complete socket policy of this protocol.
+ The \a Protocol template argument defines the protocol of the socket. This protocol provides
+ the protocol interface of the socket as well as the complete socket policy of this protocol.
- The ProtocolClientSocketHandle adds the protocol interface as an additional interface to the
- socket handle. This interface is only accessible via the protocol class. All socket
- functionality not available through the policy interface (see ClientSocketHandle) is
- accessible via the protocol() member.
+ The ProtocolClientSocketHandle adds the protocol interface as an additional interface to the
+ socket handle. This interface is only accessible via the protocol class. All socket
+ functionality not available through the policy interface (see ClientSocketHandle) is
+ accessible via the protocol() member.
- \see \ref protocol_group
+ \see \ref protocol_group
*/
template <class SocketProtocol>
class ProtocolClientSocketHandle
///\name Structors and default members
///@{
- /** \brief Create new client socket
+ /** \brief Create new client socket
- This constructor is one of the possible constructors. The exact Signature of the
- constructor (or constructors) is defined by the \c init_client() member (or members) of
- the \a Protocol class. ProtocolClientSocketHandle defines a number of constructors
- taking up to 9 arguments which just forward to a corresponding \a Protocol\c
- ::init_client() member. See the documentation of the respective Protocol class for a
- detailed documentation of that protocols constructors.
- */
+ This constructor is one of the possible constructors. The exact Signature of the
+ constructor (or constructors) is defined by the \c init_client() member (or members) of
+ the \a Protocol class. ProtocolClientSocketHandle defines a number of constructors
+ taking up to 9 arguments which just forward to a corresponding \a Protocol\c
+ ::init_client() member. See the documentation of the respective Protocol class for a
+ detailed documentation of that protocols constructors.
+ */
ProtocolClientSocketHandle();
# define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolClientSocketHandle.mpp", 1))
# include BOOST_PP_ITERATE()
-
+
///@}
///////////////////////////////////////////////////////////////////////////
Protocol const & protocol(); ///< Access the protocol interface
- /**< The returned protocol class reference gives access to
- the complete protocol interface as defined by that
- class. See the respective protocol class documentation.
- \returns \a Protocol class reference */
+ /**< The returned protocol class reference gives access to
+ the complete protocol interface as defined by that
+ class. See the respective protocol class documentation.
+ \returns \a Protocol class reference */
static ProtocolClientSocketHandle cast_static(FileHandle handle);
static ProtocolClientSocketHandle cast_dynamic(FileHandle handle);
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
MySocketHandle h;
h.protocol();
-
+
OtherSocketHandle osh (h);
h = senf::static_socket_cast<MySocketHandle>(osh);
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
-
+
/// \addtogroup handle_group
/// @{
-
+
template <class Protocol> class ProtocolClientSocketHandle;
/** \brief Protocol specific socket handle (server interface)
- The ProtocolServerSocketHandle is the server interface leaf class of the handle
- hierarchy. This is the class to instantiate to open a new socket. This is also the \e only
- class, which can be used to open a server socket.
+ The ProtocolServerSocketHandle is the server interface leaf class of the handle
+ hierarchy. This is the class to instantiate to open a new socket. This is also the \e only
+ class, which can be used to open a server socket.
- The \a Protocol template argument defines the protocol of the socket. This protocol provides
- the protocol interface of the socket as well as the complete socket policy of this protocol.
+ The \a Protocol template argument defines the protocol of the socket. This protocol provides
+ the protocol interface of the socket as well as the complete socket policy of this protocol.
- The ProtocolServerSocketHandle adds the protocol interface as an additional interface to the
- socket handle. This interface is only accessible via the protocol class. All socket
- functionality not available through the policy interface (see ServerSocketHandle) is
- accessible via the protocol() member.
+ The ProtocolServerSocketHandle adds the protocol interface as an additional interface to the
+ socket handle. This interface is only accessible via the protocol class. All socket
+ functionality not available through the policy interface (see ServerSocketHandle) is
+ accessible via the protocol() member.
- A ProtocolServerSocketHandle is only meaningful for connection oriented addressable
- protocols (CommunicationPolicy is ConnectedCommunicationPolicy and AddressingPolicy is not
- NoAddressingPolicy).
+ A ProtocolServerSocketHandle is only meaningful for connection oriented addressable
+ protocols (CommunicationPolicy is ConnectedCommunicationPolicy and AddressingPolicy is not
+ NoAddressingPolicy).
- \see \ref protocol_group
+ \see \ref protocol_group
*/
template <class SocketProtocol>
class ProtocolServerSocketHandle
///\name Structors and default members
///@{
- /** \brief Create new server socket
+ /** \brief Create new server socket
+
+ This constructor is one of the possible constructors. The exact Signature of the
+ constructor (or constructors) is defined by the \c init_server() member (or members) of
+ the \a Protocol class. ProtocolClientSocketHandle defines a number of constructors
+ taking up to 9 arguments which just forward to a corresponding \a Protocol\c
+ ::init_server() member. See the documentation of the respective Protocol class for a
+ detailed documentation of that protocols constructors.
+ */
- This constructor is one of the possible constructors. The exact Signature of the
- constructor (or constructors) is defined by the \c init_server() member (or members) of
- the \a Protocol class. ProtocolClientSocketHandle defines a number of constructors
- taking up to 9 arguments which just forward to a corresponding \a Protocol\c
- ::init_server() member. See the documentation of the respective Protocol class for a
- detailed documentation of that protocols constructors.
- */
-
ProtocolServerSocketHandle();
# define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolServerSocketHandle.mpp", 1))
///////////////////////////////////////////////////////////////////////////
Protocol const & protocol(); ///< Access the protocol interface
- /**< The returned protocol class reference gives access to
- the complete protocol interface as defined by that
- class. See the respective protocol class documentation.
- \returns \a Protocol class reference */
+ /**< The returned protocol class reference gives access to
+ the complete protocol interface as defined by that
+ class. See the respective protocol class documentation.
+ \returns \a Protocol class reference */
ProtocolClientSocketHandle<SocketProtocol> accept();
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
OtherSocketHandle osh (h);
h = senf::static_socket_cast<MySocketHandle>(osh);
-
+
MySocketHandle::ClientSocketHandle client = h.accept();
BOOST_CHECK_EQUAL( client.fd(), -1 );
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
} while (rv<0);
return rv;
}
-
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "ReadWritePolicy.mpp"
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \file
\brief ReadPolicy and WritePolicy public header
- \todo ReadWritePolicy.test.cc
+ \todo ReadWritePolicy.test.cc
*/
#ifndef HH_ReadWritePolicy_
// Custom includes
#include "SocketPolicy.hh"
#include "ClientSocketHandle.hh"
-#include "CommunicationPolicy.hh"
+#include "CommunicationPolicy.hh"
//#include "ReadWritePolicy.mpp"
///////////////////////////////hh.p////////////////////////////////////////
/// @{
/** \brief ReadPolicy for readable sockets
-
- This policy provides support for readable sockets via the standard UNIX read/recvfrom system
- cals. The concreate semantics of the read calls depend on the framing policy of the socket.
+
+ This policy provides support for readable sockets via the standard UNIX read/recvfrom system
+ cals. The concreate semantics of the read calls depend on the framing policy of the socket.
*/
struct ReadablePolicy : public ReadPolicyBase
{
static unsigned read(FileHandle handle, char * buffer, unsigned size);
///< read data from socket
/**< \param[in] handle socket handle to read from
- \param[in] buffer address of buffer to write data to
- \param[in] size size of buffer
- \returns number of bytes read */
+ \param[in] buffer address of buffer to write data to
+ \param[in] size size of buffer
+ \returns number of bytes read */
template <class Policy>
static unsigned readfrom(ClientSocketHandle<Policy> handle, char * buffer, unsigned size,
typename Policy::AddressingPolicy::Address & address,
typename IfCommunicationPolicyIs<Policy,UnconnectedCommunicationPolicy>::type * = 0);
///< read data from socket returning peer address
/**< \param[in] handle socket handle to read from
- \param[in] buffer address of buffer to write data to
- \param[in] size size of buffer
- \param[out] address peer address
- \returns number of bytes read */
+ \param[in] buffer address of buffer to write data to
+ \param[in] size size of buffer
+ \param[out] address peer address
+ \returns number of bytes read */
private:
static unsigned do_readfrom(FileHandle handle, char * buffer, unsigned size,
/** \brief ReadPolicy for unreadable sockets
- This is different from UndefinedReadPolicy (which is the same as ReadPolicyBase). This
- policy class defines the socket readability -- it explicitly states, that the socket does
- not support reading.
+ This is different from UndefinedReadPolicy (which is the same as ReadPolicyBase). This
+ policy class defines the socket readability -- it explicitly states, that the socket does
+ not support reading.
*/
struct NotReadablePolicy : public ReadPolicyBase
{};
/** \brief WritePolicy for writeable sockets
- This policy provides support for writable sockets via the standard UNIX write/sendto system
- cals. The concreate semantics of the write calls depend on the framing policy of the socket.
+ This policy provides support for writable sockets via the standard UNIX write/sendto system
+ cals. The concreate semantics of the write calls depend on the framing policy of the socket.
*/
struct WriteablePolicy : public WritePolicyBase
{
typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0);
///< write data to socket
/**< This member is only enabled if the socket uses
- connected communication. Otherwise the communication
- partner must be specified explicitly using the sendto
- call
-
- \param[in] handle socket handle to write data to
- \param[in] buffer address of buffer to send
- \param[in] size number of bytes to write
- \returns number of bytes written */
+ connected communication. Otherwise the communication
+ partner must be specified explicitly using the sendto
+ call
+
+ \param[in] handle socket handle to write data to
+ \param[in] buffer address of buffer to send
+ \param[in] size number of bytes to write
+ \returns number of bytes written */
template <class Policy>
- static unsigned writeto(ClientSocketHandle<Policy> handle,
+ static unsigned writeto(ClientSocketHandle<Policy> handle,
typename boost::call_traits<typename Policy::AddressingPolicy::Address>::param_type addr,
char const * buffer, unsigned size,
typename IfCommunicationPolicyIs<Policy,UnconnectedCommunicationPolicy>::type * = 0);
///< write data to socket sending to given peer
/**< This member is only enabled if the socket uses
- unconnected communication. Otherwise no target may be
- specified since it is implied in the connection.
+ unconnected communication. Otherwise no target may be
+ specified since it is implied in the connection.
- \param[in] handle socket handle to write data to
- \param[in] buffer address of buffer to send
- \param[in] size number of bytes to write
- \param[in] address peer to send data to
- \returns number of bytes written
- */
+ \param[in] handle socket handle to write data to
+ \param[in] buffer address of buffer to send
+ \param[in] size number of bytes to write
+ \param[in] address peer to send data to
+ \returns number of bytes written
+ */
private:
static unsigned do_write(FileHandle handle, char const * buffer, unsigned size);
static unsigned do_writeto(FileHandle handle, char const * buffer, unsigned size,
struct sockaddr * addr, socklen_t len);
};
-
+
/** \brief WritePolicy for unwriteable sockets
- This is different from UndefinedWritePolicy (which is the same as WritePolicyBase). This
- policy class defines the socket writeability -- it explicitly states, that the socket does
- not support writing.
+ This is different from UndefinedWritePolicy (which is the same as WritePolicyBase). This
+ policy class defines the socket writeability -- it explicitly states, that the socket does
+ not support writing.
*/
struct NotWriteablePolicy : public WritePolicyBase
{};
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
prefix_ typename senf::ServerSocketHandle<Policy>::ClientSocketHandle
senf::ServerSocketHandle<Policy>::acceptfrom(Address & addr)
{
- return ClientSocketHandle(this->protocol().clone(),
+ return ClientSocketHandle(this->protocol().clone(),
Policy::CommunicationPolicy::accept(*this,addr));
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief Generic SocketHandle with server interface
- This class provides the server side policy interface of the socket abstraction.
- ServerSocketHandle defines the complete policy interface. It does not implement any
- functionality itself however. All calls are forwarded to the following policy classes:
-
- <table class="senf">
- <tr><td>senf::ServerSocketHandle::bind</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td></tr>
- <tr><td>senf::ServerSocketHandle::listen</td> <td>CommunicationPolicy::listen (\ref senf::CommunicationPolicyBase)</td></tr>
- <tr><td>senf::ServerSocketHandle::local</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td></tr>
- <tr><td>senf::ServerSocketHandle::accept</td> <td>CommunicationPolicy::accept (\ref senf::CommunicationPolicyBase)</td></tr>
- <tr><td>senf::ServerSocketHandle::acceptfrom</td> <td>CommunicationPolicy::accept (\ref senf::CommunicationPolicyBase)</td></tr>
- </table>
-
- A ServerSocketHandle is only meaningful for connection oriented addressable protocols
- (CommunicationPolicy is ConnectedCommunicationPolicy and AddressingPolicy is not
- NoAddressingPolicy).
-
- It is important to note, that not all members are always accessible. Which are depends on
- the \c Policy template argument. If any of the policy axis is left unspecified the
- corresponding members will not be callable (you will get a compile time error). Even if
- every policy axis is defined, some members might (and will) not exist if they are
- meaningless for the protocol of the socket. This depends on the exact policy.
-
- To find out, which members are available, you have to check the documentation of the policy
- classes. You can also find a summary of all members available in the leaf protocol class
- documentation.
+ This class provides the server side policy interface of the socket abstraction.
+ ServerSocketHandle defines the complete policy interface. It does not implement any
+ functionality itself however. All calls are forwarded to the following policy classes:
+
+ <table class="senf">
+ <tr><td>senf::ServerSocketHandle::bind</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::listen</td> <td>CommunicationPolicy::listen (\ref senf::CommunicationPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::local</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::accept</td> <td>CommunicationPolicy::accept (\ref senf::CommunicationPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::acceptfrom</td> <td>CommunicationPolicy::accept (\ref senf::CommunicationPolicyBase)</td></tr>
+ </table>
+
+ A ServerSocketHandle is only meaningful for connection oriented addressable protocols
+ (CommunicationPolicy is ConnectedCommunicationPolicy and AddressingPolicy is not
+ NoAddressingPolicy).
+
+ It is important to note, that not all members are always accessible. Which are depends on
+ the \c Policy template argument. If any of the policy axis is left unspecified the
+ corresponding members will not be callable (you will get a compile time error). Even if
+ every policy axis is defined, some members might (and will) not exist if they are
+ meaningless for the protocol of the socket. This depends on the exact policy.
+
+ To find out, which members are available, you have to check the documentation of the policy
+ classes. You can also find a summary of all members available in the leaf protocol class
+ documentation.
*/
template <class Policy>
class ServerSocketHandle
///////////////////////////////////////////////////////////////////////////
// Types
- /// Address type from the addressing policy
+ /// Address type from the addressing policy
typedef typename Policy::AddressingPolicy::Address Address;
- /// 'Best' type for passing address as parameter
- /** Depending on the type of \c Address, this will be either <tt>Address</tt> or <tt>Address
- const &</tt>. See <a href="http://www.boost.org/libs/utility/call_traits.htm"
- class="ext">call_traits documentation in the Boost.Utility library\endlink.</a>
- */
+ /// 'Best' type for passing address as parameter
+ /** Depending on the type of \c Address, this will be either <tt>Address</tt> or <tt>Address
+ const &</tt>. See <a href="http://www.boost.org/libs/utility/call_traits.htm"
+ class="ext">call_traits documentation in the Boost.Utility library\endlink.</a>
+ */
typedef typename boost::call_traits<Address>::param_type AddressParam;
- /// Corresponding client socket handle with the same policy
+ /// Corresponding client socket handle with the same policy
typedef ClientSocketHandle<Policy> ClientSocketHandle;
///////////////////////////////////////////////////////////////////////////
typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type * = 0);
template <class OtherPolicy>
- typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const &
+ typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const &
operator=(ServerSocketHandle<OtherPolicy> other);
///@}
///\name Server socket interface
///@{
- /** \brief Set local address
-
- For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set
- the local address of the socket.
+ /** \brief Set local address
- \param[in] addr Local socket address to asign
+ For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set
+ the local address of the socket.
- \throws senf::SystemException
- */
+ \param[in] addr Local socket address to asign
+
+ \throws senf::SystemException
+ */
void bind (AddressParam addr);
- /** \brief Allow clients to connect to this server socket
-
- \todo This is very protocol specific, I don't want it in the policy
- interface. Especially the backlog argument seems quite protocol specific to
- me. However, we cannot listen() before we bind() so listen() cannot reside in the
- constructor. We need to find a good solution here.
-
- \throws senf::SystemException
- */
- // Possible solution: Make listen() an abstract method of the protocol interface, make the
- // backlog parameter into a member living in the body or protocol class and set it using
- // some accessor. Hmm ... this all seems somehow futile ...
+ /** \brief Allow clients to connect to this server socket
+
+ \todo This is very protocol specific, I don't want it in the policy
+ interface. Especially the backlog argument seems quite protocol specific to
+ me. However, we cannot listen() before we bind() so listen() cannot reside in the
+ constructor. We need to find a good solution here.
+
+ \throws senf::SystemException
+ */
+ // Possible solution: Make listen() an abstract method of the protocol interface, make the
+ // backlog parameter into a member living in the body or protocol class and set it using
+ // some accessor. Hmm ... this all seems somehow futile ...
void listen (unsigned backlog=0);
- /** \brief Query local address
+ /** \brief Query local address
- This member will return the address of the local socket in addressable protocols
- (AddressingPolicy is not NoAddressingPolicy).
+ This member will return the address of the local socket in addressable protocols
+ (AddressingPolicy is not NoAddressingPolicy).
- There are two Variants of this member, one will return the address by value, the other
- takes a reference argument to elide the copy operation.
+ There are two Variants of this member, one will return the address by value, the other
+ takes a reference argument to elide the copy operation.
- \throws senf::SystemException
- */
+ \throws senf::SystemException
+ */
Address local ();
void local (Address & addr);
///< Query local address
/**< \see \ref local() */
-
- /** \brief Accept new connection
- If the handle is non-blocking, accept will NOT block. If no connection
- is available to be returned, accept will return a ClientSocketHandle
- which is not valid()
+ /** \brief Accept new connection
- \throws senf::SystemException
+ If the handle is non-blocking, accept will NOT block. If no connection
+ is available to be returned, accept will return a ClientSocketHandle
+ which is not valid()
- This variant ...
+ \throws senf::SystemException
- \returns handle of new client connection
- */
- ClientSocketHandle
+ This variant ...
+
+ \returns handle of new client connection
+ */
+ ClientSocketHandle
accept ();
std::pair<ClientSocketHandle, Address>
- acceptfrom (); ///< Accept new connection
+ acceptfrom (); ///< Accept new connection
/**< This variant will additionally return the remote
- address of the client
- \returns \c std::pair with client handle and client
- address.
- \see \ref accept() */
+ address of the client
+ \returns \c std::pair with client handle and client
+ address.
+ \see \ref accept() */
ClientSocketHandle
acceptfrom (Address & addr);
///< Accept new connection
/**< This variant will additionally return the remote
- address of the client
- \param[out] client address
- \returns handle of new client connection
- \see \ref accept() */
-
+ address of the client
+ \param[out] client address
+ \returns handle of new client connection
+ \see \ref accept() */
+
///@}
static ServerSocketHandle cast_static(FileHandle handle);
explicit ServerSocketHandle(std::auto_ptr<SocketProtocol> protocol);
private:
-
+
};
/// @}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cc.p////////////////////////////////////////
namespace {
-
+
namespace sl = senf;
-
+
class MySocketHandle
: public sl::ServerSocketHandle<sl::test::SomeProtocol::Policy>
{
sl::test::SomeWritePolicy
>::policy OtherSocketPolicy;
typedef sl::SocketHandle<OtherSocketPolicy> OtherSocketHandle;
-
+
MySocketHandle myh;
OtherSocketHandle osh (myh);
osh = myh;
senf::NoAddressingPolicy
>::policy> SomeOtherSocketHandle;
typedef sl::ClientSocketHandle<OtherSocketPolicy> OtherClientHandle;
-
+
BOOST_CHECK_NO_THROW( sl::dynamic_socket_cast<SomeSocketHandle>(osh) );
BOOST_CHECK_THROW( sl::dynamic_socket_cast<SomeOtherSocketHandle>(osh),
std::bad_cast );
MySocketHandle::ClientSocketHandle client = myh.accept();
BOOST_CHECK_EQUAL( client.fd(), -1 );
}
-
+
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
return false;
if (contains(i2,i2_end,'.'))
// the longer string is a sub-'directory' of the shorter
- /** \fixme shouldn't this be *i2 == '.' ? */
+ /** \fixme shouldn't this be *i2 == '.' ? */
return true;
return *i1 < *i2;
}
else if (i2 == i2_end) { // && i1 != i1_end
if (contains(i1,i1_end,'.'))
// the longer string is a sub-'directory' of the shorter
- /** \fixme shouldn't this be *i1 == '.' ? */
+ /** \fixme shouldn't this be *i1 == '.' ? */
return false;
return *i1 < *i2;
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
}
template <class SocketPolicy>
-prefix_
+prefix_
senf::SocketHandle<SocketPolicy>::SocketHandle(std::auto_ptr<SocketProtocol> protocol,
bool isServer)
: FileHandle(std::auto_ptr<FileBody>(new SocketBody(protocol,isServer)))
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief basic SocketHandle supporting protocol and policy abstraction
- The senf::SocketHandle class introduces the two abstraction layers of the socket
- library. senf::SocketHandle does \e not provide socket functions it only provides the
- infrastructure necessary to support both, the protocol and the policy interface.
+ The senf::SocketHandle class introduces the two abstraction layers of the socket
+ library. senf::SocketHandle does \e not provide socket functions it only provides the
+ infrastructure necessary to support both, the protocol and the policy interface.
- senf::SocketHandle takes the socket policy as a template argument. senf::SocketHandle also
- introduces the protocol class. However, the class has no public constructors (see the
- derived classes senf::ProtocolClientSocketHandle and senf::ProtocolServerSocketHandle).
+ senf::SocketHandle takes the socket policy as a template argument. senf::SocketHandle also
+ introduces the protocol class. However, the class has no public constructors (see the
+ derived classes senf::ProtocolClientSocketHandle and senf::ProtocolServerSocketHandle).
- The most important functionality provided by senf::SocketHandle is the conversion
- constructor. This allows to implicitly convert between compatible socket handle types as
- specified by the socket policy. The conversion constructor is defined in such a way, that
- only valid conversions are possible (see the implementation source for a more complete
- discussion).
+ The most important functionality provided by senf::SocketHandle is the conversion
+ constructor. This allows to implicitly convert between compatible socket handle types as
+ specified by the socket policy. The conversion constructor is defined in such a way, that
+ only valid conversions are possible (see the implementation source for a more complete
+ discussion).
- \note This class is \e not meant to be used as a base-class outside the library
- implementation; The protected interface is for internal use only.
+ \note This class is \e not meant to be used as a base-class outside the library
+ implementation; The protected interface is for internal use only.
- \todo Create a SocketHandleBase class and move some non-Policy dependent code there
+ \todo Create a SocketHandleBase class and move some non-Policy dependent code there
*/
template <class SocketPolicy>
class SocketHandle
typedef SocketPolicy Policy;
- /** \brief Check policy compatibility
+ /** \brief Check policy compatibility
- IsCompatible is a template meta-function which will check some other socket policy for
- conversion compatibility. This check is used in the senf::SocketPolicy implementation to
- restrict the conversion operator.
- */
+ IsCompatible is a template meta-function which will check some other socket policy for
+ conversion compatibility. This check is used in the senf::SocketPolicy implementation to
+ restrict the conversion operator.
+ */
template <class OtherPolicy>
struct IsCompatible
: public boost::enable_if< SocketPolicyIsBaseOf<SocketPolicy,OtherPolicy>,
// default destructor
// conversion constructors
-
+
template <class OtherPolicy>
- SocketHandle(SocketHandle<OtherPolicy> other,
+ SocketHandle(SocketHandle<OtherPolicy> other,
typename IsCompatible<OtherPolicy>::type * = 0);
- ///< Convert from other socket handle checking policy
- ///< compatibility
+ ///< Convert from other socket handle checking policy
+ ///< compatibility
///@}
///////////////////////////////////////////////////////////////////////////
template <class OtherPolicy>
typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
- ///< Assign from other socket handle checking policy
- ///< compatibility
+ ///< Assign from other socket handle checking policy
+ ///< compatibility
void state(SocketStateMap & map, unsigned lod=0);
- ///< Inquire state information of socket handle
- /**< The map argument (a string to string mapping) will be
- filled with information coverning the current state of
- the socket. The information provided depends on the
- socket protocol. The amount of information returned can
- be controlled using the \p lod value.
-
- See senf::SocketProtocol::state() for more information,
- how the Information is generated.
-
- \param map string to string mapping to be filled with
- state information
- \param lod level of detail requesten. The interpretation
- of this value is protocol specific
-
- \implementation This member will be re-implemented in
- every derived class. This is very important since
- state() is \e not a virtual function (which we
- don't want since we don't want to add a vtable
- pointer to every handle instance). */
+ ///< Inquire state information of socket handle
+ /**< The map argument (a string to string mapping) will be
+ filled with information coverning the current state of
+ the socket. The information provided depends on the
+ socket protocol. The amount of information returned can
+ be controlled using the \p lod value.
+
+ See senf::SocketProtocol::state() for more information,
+ how the Information is generated.
+
+ \param map string to string mapping to be filled with
+ state information
+ \param lod level of detail requesten. The interpretation
+ of this value is protocol specific
+
+ \implementation This member will be re-implemented in
+ every derived class. This is very important since
+ state() is \e not a virtual function (which we
+ don't want since we don't want to add a vtable
+ pointer to every handle instance). */
std::string dumpState(unsigned lod=0);
- ///< Format complete state information as string
- /**< Formats the complete state map value and returns it as
- a single multi-line string.
+ ///< Format complete state information as string
+ /**< Formats the complete state map value and returns it as
+ a single multi-line string.
- \implementation This member will be re-implemented in
- every derived class. See the state()
- documentation. */
+ \implementation This member will be re-implemented in
+ every derived class. See the state()
+ documentation. */
protected:
explicit SocketHandle(std::auto_ptr<SocketProtocol> protocol, bool isServer);
- ///< Initialize SocketHandle providing the protocol
- /**< \param protocol Protocol class of the protocol
- implemented by this socket handle
- \param isServer \c true, if this SobcketHandle instance
- implements a server handle, \c false otherwise */
+ ///< Initialize SocketHandle providing the protocol
+ /**< \param protocol Protocol class of the protocol
+ implemented by this socket handle
+ \param isServer \c true, if this SobcketHandle instance
+ implements a server handle, \c false otherwise */
SocketHandle(FileHandle other, bool isChecked);
///< Initialize SocketHandle from arbitrary checked
///< FileHandle
- /**< This constructor is used to support up- and downcasting
- of SocketHandle instances.
+ /**< This constructor is used to support up- and downcasting
+ of SocketHandle instances.
- \warning It is absolutely necessary to ensure, that the
- FileHandle passed in is \e really a SocketHandle
- holding a SocketBody (and not a simple FileBody)
- instance. Additionally. the SocketPolicy absolutely
- must be compatible.
+ \warning It is absolutely necessary to ensure, that the
+ FileHandle passed in is \e really a SocketHandle
+ holding a SocketBody (and not a simple FileBody)
+ instance. Additionally. the SocketPolicy absolutely
+ must be compatible.
- \param other FileHandle to assign
- \param isChecked has to be \c true
+ \param other FileHandle to assign
+ \param isChecked has to be \c true
- \todo Answer, why the heck I need the \c isChecked
- parameter ??
- */
+ \todo Answer, why the heck I need the \c isChecked
+ parameter ??
+ */
- SocketBody & body(); ///< Access socket body
+ SocketBody & body(); ///< Access socket body
/**< This member replaces the corresponding FileHandle
- member and returns an appropriately cast body
- reference */
+ member and returns an appropriately cast body
+ reference */
SocketBody const & body() const; ///< Access socket body in const context
/**< This member replaces the corresponding FileHandle
- member and returns an appropriately cast body
- reference */
+ member and returns an appropriately cast body
+ reference */
SocketProtocol const & protocol() const;
///< Access protocol class
- void assign(FileHandle other); /**< \internal */
+ void assign(FileHandle other); /**< \internal */
public:
static SocketHandle cast_static(FileHandle handle);
/** \brief Write stream status dump to output stream
- Write senf::SocketHandle::dumpState() to \c os
+ Write senf::SocketHandle::dumpState() to \c os
- \related senf::SocketHandle
+ \related senf::SocketHandle
*/
template <class Policy>
std::ostream & operator<<(std::ostream & os, SocketHandle<Policy> handle);
/** \brief static socket (down-)cast
-
- This function is like \c static_cast but for socket handles. It allows to downcast any
- FileHandle to any SocketHandle (and its derived types). static_socket_cast will \e not check
- the validity of the cast, it will assume, that the cast is valid.
- The function will however check, that the cast is possible. Casting between (at compile
- time) known incompatible types (like casting a SocketHandle with a communication policy of
- ConnectedCommunicationPolicy to a SocketHandle with UnconnectedCommunicationPolicy will fail
- at compile time).
+ This function is like \c static_cast but for socket handles. It allows to downcast any
+ FileHandle to any SocketHandle (and its derived types). static_socket_cast will \e not check
+ the validity of the cast, it will assume, that the cast is valid.
+
+ The function will however check, that the cast is possible. Casting between (at compile
+ time) known incompatible types (like casting a SocketHandle with a communication policy of
+ ConnectedCommunicationPolicy to a SocketHandle with UnconnectedCommunicationPolicy will fail
+ at compile time).
- \warning
- If the type you cast to is not really a compatible socket handle type you will get undefined
- behavior, probably your program will crash (You will get an assertion in debug builds).
+ \warning
+ If the type you cast to is not really a compatible socket handle type you will get undefined
+ behavior, probably your program will crash (You will get an assertion in debug builds).
- \related senf::SocketHandle
+ \related senf::SocketHandle
*/
template <class Target, class Source>
Target static_socket_cast(Source handle);
/** \brief dynamic socket (down-)cast
- This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked
- version of static_socket_cast.
-
- \throws std::bad_cast You have tried to perform an invalid down- or crosscast.
-
- \related senf::SocketHandle
+ This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked
+ version of static_socket_cast.
+
+ \throws std::bad_cast You have tried to perform an invalid down- or crosscast.
+
+ \related senf::SocketHandle
*/
template <class Target, class Source>
Target dynamic_socket_cast(Source handle);
/** \brief dynamically check cast validity
- This function will check, wether the given cast is valid. This is the same as checking, that
- dynamic_socket_cast does not throw.
+ This function will check, wether the given cast is valid. This is the same as checking, that
+ dynamic_socket_cast does not throw.
- This member is needed, since there is no 'null' SocketHandle (comparable to a null pointer)
- which could be returned by a non-throwing variant of dynamic_socket_cast.
+ This member is needed, since there is no 'null' SocketHandle (comparable to a null pointer)
+ which could be returned by a non-throwing variant of dynamic_socket_cast.
- \related senf::SocketHandle
+ \related senf::SocketHandle
*/
template <class Target, class Source>
bool check_socket_cast(Source handle);
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace detail {
- /** \brief String supporting automatic type conversion
-
- The ConvertibleString class is used to simplify creating a text representation of
- arbitrary values. ConvertibleString is an ordinary string with an additional constructor
- which allows constructing the string from any arbitrary, streamable type.
-
- \note It is generally not advisable to derive from the standard library container
- classes. However, in this concrete case, the derivation is safe since only the
- additional functionality is added. It is absolutely safe to convert the derived class
- back to the base type.
- */
+ /** \brief String supporting automatic type conversion
+
+ The ConvertibleString class is used to simplify creating a text representation of
+ arbitrary values. ConvertibleString is an ordinary string with an additional constructor
+ which allows constructing the string from any arbitrary, streamable type.
+
+ \note It is generally not advisable to derive from the standard library container
+ classes. However, in this concrete case, the derivation is safe since only the
+ additional functionality is added. It is absolutely safe to convert the derived class
+ back to the base type.
+ */
class ConvertibleString : public std::string
{
public:
ConvertibleString();
- ConvertibleString(bool v); ///< Bool conversion constructor
- /**< The bool conversion is defined explicitly to use a
- specialized representation (the strings 'true' and
- 'false') */
+ ConvertibleString(bool v); ///< Bool conversion constructor
+ /**< The bool conversion is defined explicitly to use a
+ specialized representation (the strings 'true' and
+ 'false') */
template <class T>
ConvertibleString(T const & other);
///< Conversion constructor
/**< This constructor will assign the string from any
- arbitrary type. It will use boost::lexical_cast to
- convert the argument to its string representation. */
+ arbitrary type. It will use boost::lexical_cast to
+ convert the argument to its string representation. */
- template <class T>
- ConvertibleString & operator+= (ConvertibleString const & other);
+ template <class T>
+ ConvertibleString & operator+= (ConvertibleString const & other);
///< Add additional values with separator
/**< This operator facilitates the representation of
- multiple values in a single string. Each value is first
- converted to a string (using the type conversion
- machinery of C++ and the ConvertibleString conversion
- constructors). It is then appended to the current string
- with ', ' as a separator (if the current string is
- non-empty). */
- };
-
- /** \brief Special ordering for the SocketStateMap
- \internal
-
- This special ordering will sort 'hierarchical' strings correctly. A hierarchical string
- in this context is a string like a path- or hostname with '.' as the hierarchical
- separator.
- */
- struct StateMapOrdering
- : public std::binary_function<std::string,std::string,bool>
- {
- bool operator()(std::string const & a1, std::string const & a2) const;
- };
+ multiple values in a single string. Each value is first
+ converted to a string (using the type conversion
+ machinery of C++ and the ConvertibleString conversion
+ constructors). It is then appended to the current string
+ with ', ' as a separator (if the current string is
+ non-empty). */
+ };
+
+ /** \brief Special ordering for the SocketStateMap
+ \internal
+
+ This special ordering will sort 'hierarchical' strings correctly. A hierarchical string
+ in this context is a string like a path- or hostname with '.' as the hierarchical
+ separator.
+ */
+ struct StateMapOrdering
+ : public std::binary_function<std::string,std::string,bool>
+ {
+ bool operator()(std::string const & a1, std::string const & a2) const;
+ };
}
typedef std::map< std::string, detail::ConvertibleString, detail::StateMapOrdering > SocketStateMap;
namespace detail {
- /** \brief Helper to convert SocketStateMap to multiline string representation
- \internal
- */
- std::string dumpState(SocketStateMap const & map);
+ /** \brief Helper to convert SocketStateMap to multiline string representation
+ \internal
+ */
+ std::string dumpState(SocketStateMap const & map);
}
/** \brief SocketHandle referenced body
-
- \internal
- senf::SocketBody is the extended (relatively to senf::FileBody) body of
- senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
- FileBody). The casting and conversion operators defined will ensure this if used
- properly. If this invariant is violated, your Program will probably crash.
+ \internal
+
+ senf::SocketBody is the extended (relatively to senf::FileBody) body of
+ senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
+ FileBody). The casting and conversion operators defined will ensure this if used
+ properly. If this invariant is violated, your Program will probably crash.
*/
class SocketBody
- : public FileBody
+ : public FileBody
{
public:
- ///////////////////////////////////////////////////////////////////////////
- // Types
-
- typedef boost::intrusive_ptr<SocketBody> ptr;
-
- ///////////////////////////////////////////////////////////////////////////
- ///\name Structors and default members
- ///@{
-
- SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
- /**<
- \param protocol Protocol class implementing the desired
- protocol
- \param isServer \c true, if this socket is a server
- socket, false otherwise */
- SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
- /**<
- \param protocol Protocol class implementing the desired
- protocol
- \param isServer \c true, if this socket is a server
- socket, false otherwise
- \param fd socket file descriptor */
-
- // no copy
- // no conversion constructors
-
- ///@}
- ///////////////////////////////////////////////////////////////////////////
-
- SocketProtocol const & protocol() const;
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ typedef boost::intrusive_ptr<SocketBody> ptr;
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///@{
+
+ SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
+ /**<
+ \param protocol Protocol class implementing the desired
+ protocol
+ \param isServer \c true, if this socket is a server
+ socket, false otherwise */
+ SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
+ /**<
+ \param protocol Protocol class implementing the desired
+ protocol
+ \param isServer \c true, if this socket is a server
+ socket, false otherwise
+ \param fd socket file descriptor */
+
+ // no copy
+ // no conversion constructors
+
+ ///@}
+ ///////////////////////////////////////////////////////////////////////////
+
+ SocketProtocol const & protocol() const;
///< Access the protocol instance
- bool isServer(); ///< Check socket type
+ bool isServer(); ///< Check socket type
/**< \return \c true, if this is a server socket, \c false
- otherwise */
+ otherwise */
- void state(SocketStateMap & map, unsigned lod);
+ void state(SocketStateMap & map, unsigned lod);
private:
- virtual void v_close(); ///< Close socket
+ virtual void v_close(); ///< Close socket
/**< This override will automatically \c shutdown() the
- socket whenever it is closed.
- \throws senf::SystemException */
- virtual void v_terminate(); ///< Forcibly close socket
+ socket whenever it is closed.
+ \throws senf::SystemException */
+ virtual void v_terminate(); ///< Forcibly close socket
/**< This override will automatically \c shutfown() the
- socket whenever it is called. Additionally it will
- disable SO_LINGER to ensure, that v_terminate will not
- block. Like the overriden method, this member will ignore
- failures and will never throw. It therefore safe to be
- called from a destructor. */
- virtual bool v_eof() const; ///< Check for eof condition
+ socket whenever it is called. Additionally it will
+ disable SO_LINGER to ensure, that v_terminate will not
+ block. Like the overriden method, this member will ignore
+ failures and will never throw. It therefore safe to be
+ called from a destructor. */
+ virtual bool v_eof() const; ///< Check for eof condition
/**< Since the eof check for sockets is very protocol
- dependent, this member will forward the call to
- senf::SocketPolicy::eof() */
+ dependent, this member will forward the call to
+ senf::SocketPolicy::eof() */
- boost::scoped_ptr<SocketProtocol> protocol_;
- bool isServer_;
+ boost::scoped_ptr<SocketProtocol> protocol_;
+ bool isServer_;
};
}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
: public senf::FileHandle
{
public:
- FDHandle()
+ FDHandle()
: senf::FileHandle(std::auto_ptr<senf::FileBody>(
new senf::FileBody())) {}
};
sl::test::SomeReadPolicy
>::policy OtherSocketPolicy;
typedef sl::SocketHandle<OtherSocketPolicy> OtherSocketHandle;
-
+
MySocketHandle myh;
OtherSocketHandle osh (myh);
osh = myh;
senf::NoAddressingPolicy
>::policy> SomeOtherSocketHandle;
- BOOST_CHECK_THROW( senf::dynamic_socket_cast<SomeOtherSocketHandle>(osh),
+ BOOST_CHECK_THROW( senf::dynamic_socket_cast<SomeOtherSocketHandle>(osh),
std::bad_cast );
BOOST_CHECK_THROW( senf::dynamic_socket_cast<SomeSocketHandle>(
senf::FileHandle(FDHandle())),
std::bad_cast );
- BOOST_CHECK_EQUAL( myh.dumpState(),
+ BOOST_CHECK_EQUAL( myh.dumpState(),
"handle: senf::SocketHandle<senf::SocketPolicy<senf::test::SomeAddressingPolicy, senf::test::SomeFramingPolicy, senf::test::SomeCommunicationPolicy, senf::test::SomeReadPolicy, senf::test::SomeWritePolicy, senf::test::SomeBufferingPolicy> >\n"
"file.handle: -1\n"
"file.refcount: 3\n"
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-/** \file
+/** \file
\brief Policy Framework non-inline template implemenation
*/
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
//
// 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
+// 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
\brief Policy Framework public header
\todo We should probably remove BufferingPolicy from the
- interface, it does not make much sense (how did I come to
- include it ??)
-
+ interface, it does not make much sense (how did I come to
+ include it ??)
+
\todo Do we want to support separate read and write policies. This
- allows to treat pipes within this framework however, is this
- worth the effort?
+ allows to treat pipes within this framework however, is this
+ worth the effort?
\idea Creating a new Socket will create 4 (!) new instances (The
- handle, the body, the policy and the protocol) of which 3
- (argh) (body, policy and protocol) live on the heap. This is
- expensive. We should convert all the policy classes to
- singletons and assign the same instance to all socket bodies
- with the same policy. This would reduce the number of heap
- allocations per socket handle to two.
+ handle, the body, the policy and the protocol) of which 3
+ (argh) (body, policy and protocol) live on the heap. This is
+ expensive. We should convert all the policy classes to
+ singletons and assign the same instance to all socket bodies
+ with the same policy. This would reduce the number of heap
+ allocations per socket handle to two.
*/
/** \defgroup policy_group The Policy Framework
minimal functionality. All further functionality is relayed to a
policy class, or more precisely, to a group of policy classes, one
for each policy axis. The policy axis are
-
+
<dl>
<dt><em>addressingPolicy</em></dt>
<dd>configures, whether a socket is
addressable and if so, configures the address type</dd>
-
+
<dt><em>framingPolicy</em></dt>
<dd>configures the type of framing the socket provides: either no
framing providing a simple i/o stream or packet framing</dd>
-
+
<dt><em>communicationPolicy</em></dt>
<dd>configures,if and how the communication partner is
- selected</dd>
-
+ selected</dd>
+
<dt><em>readPolicy</em></dt>
<dd>configures the readability of the socket</dd>
-
+
<dt><em>writePolicy</em></dt>
<dd>configures the writability of the socket</dd>
-
+
<dt><em>bufferingPolicy</em></dt>
<dd>configures, if and how buffering is configured for a socket</dd>
</dl>
Two SocketHandle's with different policies can be \e
compatible. If they are, the more derived SocketHandle can be
converted (assigned to) the more basic SocketHandle.
-
+
\section policy_group_details The Policy Framework Classes
In the following discussion we will use the following conventions:
\li \e Policy is one or \c AddressingPolicy, \c FramingPolicy, \c
- CommunicationPolicy, \c ReadPolicy, \c WritePolicy or \c
- BufferingPolicy
+ CommunicationPolicy, \c ReadPolicy, \c WritePolicy or \c
+ BufferingPolicy
\li \e socketPolicy is any socket policy (that is, an
- instantiation of the SocketPolicy template)
+ instantiation of the SocketPolicy template)
\li \e trait is an any policy class (that is, any class derived
- from one of the axis base classes)
+ from one of the axis base classes)
Each axis is comprised of a number of classes and templates (all
in namespace senf of course):
-
+
<dl>
<dt>\e Policy \c Base (ex: AddressingPolicyBase)</dt>
<dd>Baseclass of all policies in this axis</dd>
<dt>\c If \e Policy \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
<dd>The inverse of above</dd>
</dl>
-
+
These classes form the basis of the policy framework. To bind the
policy axis together, there are some more classes and templates.
specify the call signature not the way, the member must be defined
(FileHandle really is not a FileHandle but an arbitrary
SocketHandle).
-
+
If the existence of a member depends on other policies, you should
use the <code>If</code><i>SomePolicy</i><code>Is</code> and
<code>If</code><i>SomePolicy</i><code>IsNot</code> templates to
policy:
\code
- struct ExampleAddressingPolicy
+ struct ExampleAddressingPolicy
{
- template <class Policy>
- void connect(senf::SocketHandle<Policy> handle, Address & addr,
- typename senf::IfCommmunicationPolicyIs<
- Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
+ template <class Policy>
+ void connect(senf::SocketHandle<Policy> handle, Address & addr,
+ typename senf::IfCommmunicationPolicyIs<
+ Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
};
\endcode
// be adjusted accordingly)
/** \brief List all policy axis
-
- \internal
- This define symbol is used to configure the policy axis. The
- base class for each of these axis must be defined explicitly
- (e.g. AddressingPolicyBase). The implementation files will
- then automatically generate all the other classes from this
- list.
+ \internal
- \see policy_group
+ This define symbol is used to configure the policy axis. The
+ base class for each of these axis must be defined explicitly
+ (e.g. AddressingPolicyBase). The implementation files will
+ then automatically generate all the other classes from this
+ list.
+
+ \see policy_group
*/
-# define SENF_SOCKET_POLICIES \
- (AddressingPolicy) \
- (FramingPolicy) \
- (CommunicationPolicy) \
- (ReadPolicy) \
- (WritePolicy) \
- (BufferingPolicy)
+# define SENF_SOCKET_POLICIES \
+ (AddressingPolicy) \
+ (FramingPolicy) \
+ (CommunicationPolicy) \
+ (ReadPolicy) \
+ (WritePolicy) \
+ (BufferingPolicy)
// Wer define these classes explicitly (and not with some macro
// magic) because
// a) AddressingPolicyBase is different from all the others
// b) We want to document each one explicitly
-
+
/** \brief Policy defining socket addressing
- AddressingPolicyBase is the baseclass of all addressing policy
- classes. When defining a new addressing policy, the following
- members can be defined. All methods must be static.
+ AddressingPolicyBase is the baseclass of all addressing policy
+ classes. When defining a new addressing policy, the following
+ members can be defined. All methods must be static.
- <table class="senf">
- <tr><td>typedef</td> <td><tt>Address</tt></td> <td>Address type</td></tr>
- <tr><td>method</td> <td><tt>void local(FileHandle, Address &)</tt></td> <td>Get local socket address</td></tr>
- <tr><td>method</td> <td><tt>void peer(FileHandle, Address &)</tt></td> <td>Get remote socket address</td></tr>
- <tr><td>method</td> <td><tt>void bind(FileHandle, Address const &)</tt></td> <td>Bind socket to local address</td></tr>
- <tr><td>method</tr> <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
- </table>
+ <table class="senf">
+ <tr><td>typedef</td> <td><tt>Address</tt></td> <td>Address type</td></tr>
+ <tr><td>method</td> <td><tt>void local(FileHandle, Address &)</tt></td> <td>Get local socket address</td></tr>
+ <tr><td>method</td> <td><tt>void peer(FileHandle, Address &)</tt></td> <td>Get remote socket address</td></tr>
+ <tr><td>method</td> <td><tt>void bind(FileHandle, Address const &)</tt></td> <td>Bind socket to local address</td></tr>
+ <tr><td>method</tr> <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
+ </table>
- \see policy_group
+ \see policy_group
*/
struct AddressingPolicyBase
{
- virtual ~AddressingPolicyBase() {}
-
- typedef GenericSockAddr Address;
+ virtual ~AddressingPolicyBase() {}
+
+ typedef GenericSockAddr Address;
};
/** \brief Policy defining the framing format
- This policy does not define any operations since it does have
- no influence on any method signature. It does however affect
- the semantics of the \c read() and \c write() operations.
+ This policy does not define any operations since it does have
+ no influence on any method signature. It does however affect
+ the semantics of the \c read() and \c write() operations.
- \note This policy axis probably only has two sensible statess:
- StreamFramingPolicy and DatagramFramingPolicy.
+ \note This policy axis probably only has two sensible statess:
+ StreamFramingPolicy and DatagramFramingPolicy.
- \see policy_group
+ \see policy_group
*/
- struct FramingPolicyBase
+ struct FramingPolicyBase
{
- virtual ~FramingPolicyBase() {}
+ virtual ~FramingPolicyBase() {}
};
/** \brief Policy defining, how peers are selected
- The CommunicationPolicy may define two members:
-
- <table class="senf">
- <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
- <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td> <td>Accept a new connection</td></tr>
- </table>
-
- The \c listen member is straight forward. The \c accept() member
- must return a new file descriptor (which will be used to
- create a new SocketHandle of the correct type). Additionally,
- accept() should only be defined, if the Addressing policy is
- not \c NoAddressingPolicy (which together with
- ConnectedCommunicationPolicy would identify a point-to-point
- link with fixed communication partners).
-
- \note This Policy only has two meaningful states:
- ConnectedCommunicationPolicy and
- UnconnectedCommunicationPolicy. It is probably not sensible to
- define a new CommunicationPolicy type.
-
- \see policy_group
+ The CommunicationPolicy may define two members:
+
+ <table class="senf">
+ <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
+ <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td> <td>Accept a new connection</td></tr>
+ </table>
+
+ The \c listen member is straight forward. The \c accept() member
+ must return a new file descriptor (which will be used to
+ create a new SocketHandle of the correct type). Additionally,
+ accept() should only be defined, if the Addressing policy is
+ not \c NoAddressingPolicy (which together with
+ ConnectedCommunicationPolicy would identify a point-to-point
+ link with fixed communication partners).
+
+ \note This Policy only has two meaningful states:
+ ConnectedCommunicationPolicy and
+ UnconnectedCommunicationPolicy. It is probably not sensible to
+ define a new CommunicationPolicy type.
+
+ \see policy_group
*/
struct CommunicationPolicyBase
{
- virtual ~CommunicationPolicyBase() {}
+ virtual ~CommunicationPolicyBase() {}
};
/** \brief Policy defining the readability
- The ReadPolicy defines, wether the socket is readable. It
- may define two members:
+ The ReadPolicy defines, wether the socket is readable. It
+ may define two members:
- <table class="senf">
- <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
- <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
- </table>
+ <table class="senf">
+ <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
+ <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
+ </table>
- The second member should only be enabled if the communication
- policy is UnconnectedCommunication (otherwise it does not make
- sense since the communication partner is fixed) (see
- AddressingPolicyBase on how to do this).
+ The second member should only be enabled if the communication
+ policy is UnconnectedCommunication (otherwise it does not make
+ sense since the communication partner is fixed) (see
+ AddressingPolicyBase on how to do this).
- \note This Policy only has two meaningful states:
- ReadablePolicy and NotReadablePolicy. It probably does not
- make sense to define new read policy types.
+ \note This Policy only has two meaningful states:
+ ReadablePolicy and NotReadablePolicy. It probably does not
+ make sense to define new read policy types.
- \see policy_group
+ \see policy_group
*/
struct ReadPolicyBase
{
- virtual ~ReadPolicyBase() {}
+ virtual ~ReadPolicyBase() {}
};
/** \brief Policy defining the writability
- The WritePolicy defines, wether the socket is writable. It may
- define two members:
+ The WritePolicy defines, wether the socket is writable. It may
+ define two members:
- <table class="senf">
- <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
- <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
- </table>
+ <table class="senf">
+ <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
+ <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
+ </table>
- The second member should only be enabled if the communication
- policy is UnconnectedCommunication (otherwise it does not make
- sense since the communication partner is fixed) (see
- AddressingPolicyBase on how to do this).
+ The second member should only be enabled if the communication
+ policy is UnconnectedCommunication (otherwise it does not make
+ sense since the communication partner is fixed) (see
+ AddressingPolicyBase on how to do this).
- \note This Policy only has two meaningful states:
- WritablePolicy and NotWritablePolicy. It probably does not
- make sense to define new write policy types.
+ \note This Policy only has two meaningful states:
+ WritablePolicy and NotWritablePolicy. It probably does not
+ make sense to define new write policy types.
- \see policy_group
+ \see policy_group
*/
struct WritePolicyBase
{
- virtual ~WritePolicyBase() {}
+ virtual ~WritePolicyBase() {}
};
-
+
/** \brief Policy defining the buffering interface
- The BufferingPolicy defines the buffer handling of the
- socket. It may provide the follogin members:
-
- \see policy_group
+ The BufferingPolicy defines the buffer handling of the
+ socket. It may provide the follogin members:
+
+ \see policy_group
*/
struct BufferingPolicyBase
{
- virtual ~BufferingPolicyBase() {}
+ virtual ~BufferingPolicyBase() {}
};
-
+
// The implementation file will for each Policy declared above
// define the following (SomePolicy is one of the above):
//
// The following stub definitions are only visible to doxygen
/** \brief Alias of AddressingPolicyBase for better readability
- \see \ref policy_group
+ \see \ref policy_group
*/
typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
-
+
/** \brief Check single policy axis
-
- This template is an example of the \e Policy \c Is family of
- tempalte metafunctions. It will check, wether \c Trait is a
- valid compatible Policy class of \c SocketPolicy. \c Trait
- must be derived from AddressingPolicyBase (respectively \i
- Policy \c Base).
-
- \see \ref policy_group
+
+ This template is an example of the \e Policy \c Is family of
+ tempalte metafunctions. It will check, wether \c Trait is a
+ valid compatible Policy class of \c SocketPolicy. \c Trait
+ must be derived from AddressingPolicyBase (respectively \i
+ Policy \c Base).
+
+ \see \ref policy_group
*/
template <class SocketPolicy, class Trait>
struct AddressingPolicyIs
/** \brief Enable template overload depending on policy value
- This template is an exmaple of the \c If \e Policy \c Is
- family of templates. It is used like <a class="ext"
- href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
- to enable a templated overload only, if the AddressingPolicy
- of \e Policy is compatible with \c Trait (that is the
- AddressingPolicy of \c Policy is derived from \c Trait).
+ This template is an exmaple of the \c If \e Policy \c Is
+ family of templates. It is used like <a class="ext"
+ href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
+ to enable a templated overload only, if the AddressingPolicy
+ of \e Policy is compatible with \c Trait (that is the
+ AddressingPolicy of \c Policy is derived from \c Trait).
- \see policy_group
+ \see policy_group
*/
template <class SocketPolicy, class Trait>
struct IfAddressingPolicyIs
{};
/** \brief Inversion of \c IfAddressingPolicyIs
- \see policy_group
+ \see policy_group
*/
template <class SocketPolicy, class Trait>
struct IfAddressingPolicyIsNot
/** \brief Baseclass of all SocketPolicies
- \internal
+ \internal
- This class provides the baseclass of all socket policies
- (bundles). It serves two purposes:
- \li It allows us to easily identify a socket policy bundle by
- checking a classes baseclass.
- \li It provides an abstract (virtual) interface to access the
- policy axes
+ This class provides the baseclass of all socket policies
+ (bundles). It serves two purposes:
+ \li It allows us to easily identify a socket policy bundle by
+ checking a classes baseclass.
+ \li It provides an abstract (virtual) interface to access the
+ policy axes
- \see policy_group
+ \see policy_group
*/
struct SocketPolicyBase
{
- /** \brief Polymorphic access to policy axes
-
- This is an example of a policy axes accessor. It returns a
- reference to the policy axes used by the conrecte protocol
- bundle. This reference can then be checked using RTTI
- information.
- */
- AddressingPolicyBase const & theAddressingPolicy() const = 0;
+ /** \brief Polymorphic access to policy axes
+
+ This is an example of a policy axes accessor. It returns a
+ reference to the policy axes used by the conrecte protocol
+ bundle. This reference can then be checked using RTTI
+ information.
+ */
+ AddressingPolicyBase const & theAddressingPolicy() const = 0;
};
/** \brief Collection of policy classes
-
- The SocketPolicy template defines the complete Policy used by
- the socket library. It contains one policy class for each
- policy axis. This template takes one policy from each axis as
- it's template arguments (this example implementation only has
- AddressingPolicy as an argument).
-
- A SocketPolicy can be complete or incomplete. An incomplete
- SocketPolicy will have at least one axis set to \c Undefined
- \e Policy (or a generic derived class which is used to group
- some other policies but does not (completely) define the
- policy behavior). A complete SocketPolicy will have a
- concrete definition of the desired behavior for each policy
- axis.
-
- \see policy_group
+
+ The SocketPolicy template defines the complete Policy used by
+ the socket library. It contains one policy class for each
+ policy axis. This template takes one policy from each axis as
+ it's template arguments (this example implementation only has
+ AddressingPolicy as an argument).
+
+ A SocketPolicy can be complete or incomplete. An incomplete
+ SocketPolicy will have at least one axis set to \c Undefined
+ \e Policy (or a generic derived class which is used to group
+ some other policies but does not (completely) define the
+ policy behavior). A complete SocketPolicy will have a
+ concrete definition of the desired behavior for each policy
+ axis.
+
+ \see policy_group
*/
template < class AddressingPolicy >
struct SocketPolicy
{
- /** \brief Check dynamic policy compatibility
-
- This method will check the socket policy \a other against
- this policy. It will check, wether \a other is a base
- policy (or the same) of this policy. This check is done
- against the \e dynamic type of \a other using RTTI. It
- will throw \c std::bad_cast, if the policy is not
- compatible.
-
- \param[in] other SocketPolicy to check
- \throws std::bad_cast if \a other is not a compatible
- policy
- */
- static void checkBaseOf(SocketPolicyBase const & other);
+ /** \brief Check dynamic policy compatibility
+
+ This method will check the socket policy \a other against
+ this policy. It will check, wether \a other is a base
+ policy (or the same) of this policy. This check is done
+ against the \e dynamic type of \a other using RTTI. It
+ will throw \c std::bad_cast, if the policy is not
+ compatible.
+
+ \param[in] other SocketPolicy to check
+ \throws std::bad_cast if \a other is not a compatible
+ policy
+ */
+ static void checkBaseOf(SocketPolicyBase const & other);
};
-
+
/** \brief Metafunction to create SocketPolicy
-
- This template metafunction simplifies the creation of a
- SocketPolicy instantiation. It takes any number (that is up to
- 6) of Policy classes as arguments in any Order. It will create
- a SocketPolicy from these policy classes. Any axis not
- specified will be left as \c Unspecified \e Policy.
-
- \see policy_group
+
+ This template metafunction simplifies the creation of a
+ SocketPolicy instantiation. It takes any number (that is up to
+ 6) of Policy classes as arguments in any Order. It will create
+ a SocketPolicy from these policy classes. Any axis not
+ specified will be left as \c Unspecified \e Policy.
+
+ \see policy_group
*/
template <class Arg1, class Arg2, class ArgN>
struct MakeSocketPolicy
/** \brief Check policy compatibility
- This tempalte metafunction checks, wether the SocketPolicy \c
- Derived is more specialized than \c Base (and therefore a
- SocketHandle with policy \c Derived is convertible to a
- SocketHandle with policy \c Base).
+ This tempalte metafunction checks, wether the SocketPolicy \c
+ Derived is more specialized than \c Base (and therefore a
+ SocketHandle with policy \c Derived is convertible to a
+ SocketHandle with policy \c Base).
- The metafunction will return true (that is inherits from \c
- boost::true_type, see the <a class="ext"
- href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
- library documentation for more information) if each policy
- class in \c Base is a baseclass of (or the same as) the
- corresponding policy class in \c Derived.
+ The metafunction will return true (that is inherits from \c
+ boost::true_type, see the <a class="ext"
+ href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
+ library documentation for more information) if each policy
+ class in \c Base is a baseclass of (or the same as) the
+ corresponding policy class in \c Derived.
- \see policy_group
+ \see policy_group
*/
template <class Base, class Derived>
struct SocketPolicyIsBaseOf
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace senf {
# define SENF_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SENF_SOCKET_POLICIES )
-
+
# define SP_DeclareAlias(x1,x2,SomePolicy) \
typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy);
BOOST_PP_SEQ_FOR_EACH( SP_DeclareAlias, , SENF_SOCKET_POLICIES )
# undef SP_DeclareAlias
-
+
struct SocketPolicyBase
{
virtual ~SocketPolicyBase() {}
-# define SP_Declare(x1,x2,SomePolicy) \
+# define SP_Declare(x1,x2,SomePolicy) \
virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const = 0;
BOOST_PP_SEQ_FOR_EACH( SP_Declare, , SENF_SOCKET_POLICIES )
template <int N>
struct SocketPolicy_rv
{ int v[N+1]; };
-
+
template <class Base, class Policy, int N>
struct MakeSocketPolicy_merge
{};
BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy )
# define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SENF_SOCKET_POLICIES_N ) )
-# define BOOST_PP_LOCAL_MACRO(n) \
- SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SENF_SOCKET_POLICIES ),Base)*); \
- \
- template <class Base, class Policy> \
- struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<n>)> \
- { \
- typedef SocketPolicy< \
- BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, n, SENF_SOCKET_POLICIES ) \
- > type; \
+# define BOOST_PP_LOCAL_MACRO(n) \
+ SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SENF_SOCKET_POLICIES ),Base)*); \
+ \
+ template <class Base, class Policy> \
+ struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<n>)> \
+ { \
+ typedef SocketPolicy< \
+ BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, n, SENF_SOCKET_POLICIES ) \
+ > type; \
};
# include BOOST_PP_LOCAL_ITERATE()
};
# define SP_DeclareArguments(x1,x2,n,SomePolicy) \
- BOOST_PP_COMMA_IF( n ) \
- typename Base::SomePolicy *
+ BOOST_PP_COMMA_IF( n ) \
+ typename Base::SomePolicy *
template <class Base>
SocketPolicy_rv<1> SocketPolicy_checkcompat_(
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
struct WritablePolicy : public WritePolicyBase {};
struct UnwritablePolicy : public WritePolicyBase {};
-
+
struct SocketBufferingPolicy : public BufferingPolicyBase {};
template <class Policy>
ConvertibleValue(ConvertibleValue const & other) {}
template <class OtherPolicy>
- ConvertibleValue(ConvertibleValue<OtherPolicy> const & other,
+ ConvertibleValue(ConvertibleValue<OtherPolicy> const & other,
typename boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy> >::type * = 0)
{}
{ return *this; }
template <class OtherPolicy>
- typename boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy>,
- ConvertibleValue >::type const &
+ typename boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy>,
+ ConvertibleValue >::type const &
operator=(ConvertibleValue<OtherPolicy> const & other)
{ return *this; }
};
ReadablePolicy,
UnspecifiedWritePolicy,
UnspecifiedBufferingPolicy> Policy2;
-
+
BOOST_MPL_ASSERT(( boost::is_same<Policy1,Policy2> ));
typedef MakeSocketPolicy<
// The following should fail at compile time
// BOOST_MPL_ASSERT(( SocketPolicyIsBaseOf<Policy1,Policy3> ));
-
+
ConvertibleValue<Policy1> p1;
ConvertibleValue<Policy3> p3(p1);
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
struct SomeAddressingPolicy : public senf::AddressingPolicyBase
{
typedef unsigned Address;
-
+
static void peer(FileHandle handle, unsigned & addr)
{ addr=1; }
static void local(FileHandle, unsigned & addr)
return write(handle,buffer,size);
}
};
-
+
struct SomeBufferingPolicy : public senf::BufferingPolicyBase
{
static unsigned rcvbuf(FileHandle handle)
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \file
\brief SocketProtocol and ConcreteSocketProtocol public header
-
+
\idea We should optimize the protocol handling. Allocating a protocol instance for every socket
- body seems quite wasteful. We could derive SocketPolicy from SocketBody (probably privately,
- since private inheritance models more of 'has a' than 'is a'). This would allow to reduce
- the number of heap-allocations per socket to one which is good.
+ body seems quite wasteful. We could derive SocketPolicy from SocketBody (probably privately,
+ since private inheritance models more of 'has a' than 'is a'). This would allow to reduce
+ the number of heap-allocations per socket to one which is good.
*/
// The private inheritance idea should indeed work very well: We just need to chnage the
policy axis must be assigned it's the most specific (that is derived) policy class to be used
with the protocol.
- \see
- \ref handle_group \n
- \ref policy_group
+ \see
+ \ref handle_group \n
+ \ref policy_group
\todo Complete the protocol interface implementations. Better distribution of members to
- protocol facets and more precise distribution of functionality among the facets.
+ protocol facets and more precise distribution of functionality among the facets.
*/
/** \defgroup concrete_protocol_group Protocol Implementations (Concrete Protocol Classes)
Theese protocol classes define concrete and complete protocol implementations. They inherit from
ConcreteSocketProtocol and are used with the ProtocolClientSocketHandle and
ProtocolServerSocketHandle templates to instantiate socket handles. Appropriate typedefs are
- always provided.
-
+ always provided.
+
Every protocol defines both the protocol and the policy interface provided by that protocol. See
the documentation of the protocol classes listed below for more information on the supported
protocols. Every protocol class documents it's policy interface. Use the 'list all members' link
/** \brief Socket protocol base class
- This is the base class of all socket protocol classes. Every protocol class must directly or
- indirectly inherit from SocketProtocol
-
- \attention SocketProtocol must \e always be inherited using public \e virtual inheritance.
+ This is the base class of all socket protocol classes. Every protocol class must directly or
+ indirectly inherit from SocketProtocol
+
+ \attention SocketProtocol must \e always be inherited using public \e virtual inheritance.
*/
class SocketProtocol : boost::noncopyable
{
///////////////////////////////////////////////////////////////////////////
SocketBody & body() const; ///< Access the socket body
- /**< \todo we don't need body(), we should better provide a
- handle() member which will return a simple FIleHandle
- object (we cannot return some other derived class since
- we don't know the Protocol or Policy at this point) */
+ /**< \todo we don't need body(), we should better provide a
+ handle() member which will return a simple FIleHandle
+ object (we cannot return some other derived class since
+ we don't know the Protocol or Policy at this point) */
virtual SocketPolicyBase const & policy() const = 0;
///< Access the policy instance
-
+
///////////////////////////////////////////////////////////////////////////
// Virtual interface
virtual std::auto_ptr<SocketProtocol> clone() const = 0;
///< Polymorphically return a copy of this protocol class
/**< This member will create a new copy of the protocol
- class on the heap.
- \attention This member must be implemented in every \e
- leaf protocol class to return a new instance of the
- appropriate type. */
+ class on the heap.
+ \attention This member must be implemented in every \e
+ leaf protocol class to return a new instance of the
+ appropriate type. */
virtual unsigned available() const = 0;
///< Return number of bytes available for reading without
///< blocking
/**< This member will check in a (very, sigh) protocol
- deqpendent way, how many bytes are guarateed to be
- readable from the socket without blocking even if the
- socket is blocking. */
+ deqpendent way, how many bytes are guarateed to be
+ readable from the socket without blocking even if the
+ socket is blocking. */
virtual bool eof() const = 0; ///< Check for end-of-file condition
/**< This is another check which (like available()) is
- extremely protocol dependent. This member will return
- \c true only, if at end-of-file. If the protocol does
- not support the notion of EOF, this member should
- always return \c false. */
+ extremely protocol dependent. This member will return
+ \c true only, if at end-of-file. If the protocol does
+ not support the notion of EOF, this member should
+ always return \c false. */
virtual void state(SocketStateMap & map, unsigned lod) const;
///< Return socket state information
/**< This member is called to add state information to the
- status \a map. The protocol map should provide as
- detailed information as possible. The amount of
- information to be added to the map is selected by the
- \a lod value with a default value of 0. The
- interpretation of the \a lod value is completely
- implementation defined.
-
- Every class derived from SocketProtocol should
- reimplement state(). The reimplemented method should
- call (all) baseclass-implementations of this
- member.
-
- The \a map Argument is a map which associates
- std:string keys with std:string-like values. The map
- keys are interpreted as hierarchical strings with '.'
- as a separator (like hostnames or struct or class
- members). They are automatically sorted correctly.
-
- The values are std:string with one additional feature:
- they allow assignment or conversion from *any* type as
- long as that type is streamable. This simplifies
- assigning non-string values to the map:
-
- \code
- map["socket.protocol.ip.address"] = peer();
- map["socket.protocol.tcp.backlog"] = backlog();
- \endcode
-
- This will work even if peer() returns an ip-address
- object or backlog() returns an integer. The values are
- automatically converted to their string representation.
-
- The operator "+=" also has been reimplemented to
- simplify adding multiple values to a single entry: It
- will automatically add a ", " separator if the string
- is non-empty. */
+ status \a map. The protocol map should provide as
+ detailed information as possible. The amount of
+ information to be added to the map is selected by the
+ \a lod value with a default value of 0. The
+ interpretation of the \a lod value is completely
+ implementation defined.
+
+ Every class derived from SocketProtocol should
+ reimplement state(). The reimplemented method should
+ call (all) baseclass-implementations of this
+ member.
+
+ The \a map Argument is a map which associates
+ std:string keys with std:string-like values. The map
+ keys are interpreted as hierarchical strings with '.'
+ as a separator (like hostnames or struct or class
+ members). They are automatically sorted correctly.
+
+ The values are std:string with one additional feature:
+ they allow assignment or conversion from *any* type as
+ long as that type is streamable. This simplifies
+ assigning non-string values to the map:
+
+ \code
+ map["socket.protocol.ip.address"] = peer();
+ map["socket.protocol.tcp.backlog"] = backlog();
+ \endcode
+
+ This will work even if peer() returns an ip-address
+ object or backlog() returns an integer. The values are
+ automatically converted to their string representation.
+
+ The operator "+=" also has been reimplemented to
+ simplify adding multiple values to a single entry: It
+ will automatically add a ", " separator if the string
+ is non-empty. */
protected:
private:
// backpointer to owning SocketBody instance
SocketBody * body_;
- friend class SocketBody;
+ friend class SocketBody;
};
-
+
/** \brief Concrete socket protocol implementation base class
-
- ConcreteSocketProtocol is the base class of a concrete socket protocol implementation. The
- final protocol class must inherit from ConcreteSocketProtocol. The template argument \a
- SocketPolicy must be set to the complete socket policy of the protocol.
-
- A protocol implementation may define the protocol interface directly. It can also
- (additnally) make use of multiple inheritance to combine a set of protocol facets into a
- specific protocol implementation (i.e. TCPv4SocketProtocol inherits from
- ConcreteSocketProtocol and from the protocol facets IPv4Protocol, TCPProtocol,
- BSDSocketProtocol and AddressableBSDSocketProtocol). The protocol facets are not concrete
- protocols themselves, they are combined to build concrete protocols. This structure will
- remove a lot of code duplication. It is important to ensure, that the protocol facets do not
- overlap, since otherwise there will be problems resolving overlapping members.
+
+ ConcreteSocketProtocol is the base class of a concrete socket protocol implementation. The
+ final protocol class must inherit from ConcreteSocketProtocol. The template argument \a
+ SocketPolicy must be set to the complete socket policy of the protocol.
+
+ A protocol implementation may define the protocol interface directly. It can also
+ (additnally) make use of multiple inheritance to combine a set of protocol facets into a
+ specific protocol implementation (i.e. TCPv4SocketProtocol inherits from
+ ConcreteSocketProtocol and from the protocol facets IPv4Protocol, TCPProtocol,
+ BSDSocketProtocol and AddressableBSDSocketProtocol). The protocol facets are not concrete
+ protocols themselves, they are combined to build concrete protocols. This structure will
+ remove a lot of code duplication. It is important to ensure, that the protocol facets do not
+ overlap, since otherwise there will be problems resolving overlapping members.
*/
template <class SocketPolicy>
class ConcreteSocketProtocol
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
senf::test::SomeProtocol protocol;
// This would fail an assertion ...
- // BOOST_CHECK( protocol.body() == 0 );
+ // BOOST_CHECK( protocol.body() == 0 );
protocol.policy();
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
{
public:
~SomeProtocol() {}
-
+
void init_client() const {}
void init_server() const {}
- std::auto_ptr<SocketProtocol> clone() const
+ std::auto_ptr<SocketProtocol> clone() const
{ return std::auto_ptr<SocketProtocol>(new SomeProtocol()); }
- unsigned available() const
+ unsigned available() const
{ return Policy::ReadPolicy::TEST_SIZE; }
- bool eof() const
+ bool eof() const
{ return false; }
};
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/// @{
/** \brief Protocol facat to support TCP operations
-
- This protocol facet provides all those protocol functions,
- which are available on any TCP socket.
+
+ This protocol facet provides all those protocol functions,
+ which are available on any TCP socket.
*/
class TCPProtocol
: public virtual SocketProtocol
bool nodelay() const; ///< Check current \c SO_NODELAY status
void nodelay(bool value) const; ///< Set \c SO_NODELAY status
/**< Enabling \c SO_NODELAY will disable the NAGLE
- algorithm (which aggregates multiple writes into a
- single network packet). Enabling nodelay() optimizes
- the repsonse time at the expense of the bandwidth
- efficiency.
- \param[in] value \c SO_NODELAY state */
+ algorithm (which aggregates multiple writes into a
+ single network packet). Enabling nodelay() optimizes
+ the repsonse time at the expense of the bandwidth
+ efficiency.
+ \param[in] value \c SO_NODELAY state */
unsigned siocinq() const; ///< Return current size of the input queue
unsigned siocoutq() const; ///< Return current size of the output queue
- ///\name Abstract Interface Implementation
- ///@{
+ ///\name Abstract Interface Implementation
+ ///@{
unsigned available() const;
bool eof() const;
- ///@}
+ ///@}
};
/// @}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
}
prefix_ void senf::TCPv6SocketProtocol::init_server(INet6SocketAddress const & address,
- unsigned backlog)
+ unsigned backlog)
const
{
init_server();
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
>::policy TCPv4Socket_Policy; ///< Socket Policy of the TCPv4 Protocol
/** \brief IPv4 TCP Socket Protocol
-
- \par Socket Handle typedefs:
- \ref TCPv4ClientSocketHandle (ProtocolClientSocketHandle), \ref TCPv4ServerSocketHandle
- (ProtocolServerSocketHandle)
-
- \par Protocol Interface:
- ClientSocketHandle::read(), ClientSocketHandle::write(), ClientSocketHandle::bind(),
- ClientSocketHandle::local(), ClientSocketHandle::connect(), ClientSocketHandle::peer(),
- ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf()
-
- \par Address Type:
- INet4Address
-
- TCPv4SocketProtocol provides an internet protocol stream socket based on the TCP protocol
- and IPv4 addressing.
-
- This class is utilized as the protocol class of the ProtocolClientSocketHandle and
- ProtocolServerSocketHandle via the Socket Handle typedefs above.
-
- \see TCPv6SocketProtocol
+
+ \par Socket Handle typedefs:
+ \ref TCPv4ClientSocketHandle (ProtocolClientSocketHandle), \ref TCPv4ServerSocketHandle
+ (ProtocolServerSocketHandle)
+
+ \par Protocol Interface:
+ ClientSocketHandle::read(), ClientSocketHandle::write(), ClientSocketHandle::bind(),
+ ClientSocketHandle::local(), ClientSocketHandle::connect(), ClientSocketHandle::peer(),
+ ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf()
+
+ \par Address Type:
+ INet4Address
+
+ TCPv4SocketProtocol provides an internet protocol stream socket based on the TCP protocol
+ and IPv4 addressing.
+
+ This class is utilized as the protocol class of the ProtocolClientSocketHandle and
+ ProtocolServerSocketHandle via the Socket Handle typedefs above.
+
+ \see TCPv6SocketProtocol
*/
class TCPv4SocketProtocol
: public ConcreteSocketProtocol<TCPv4Socket_Policy>,
- public IPv4Protocol,
+ public IPv4Protocol,
public TCPProtocol,
public BSDSocketProtocol,
public AddressableBSDSocketProtocol
///////////////////////////////////////////////////////////////////////////
// internal interface
- ///\name Constructors
- ///@{
+ ///\name Constructors
+ ///@{
void init_client() const; ///< Create unconnected client socket
- /**< \note This member is implicitly called from the
- ProtocolClientSocketHandle::ProtocolClientSocketHandle()
- constructor */
+ /**< \note This member is implicitly called from the
+ ProtocolClientSocketHandle::ProtocolClientSocketHandle()
+ constructor */
void init_client(INet4Address const & address) const;
///< Create client socket and connect
/**< Creates a new client socket and connects to the given
- address.
-
- \param[in] address remote address to connect to */
- /**< \note This member is implicitly called from the
- ProtocolClientSocketHandle::ProtocolClientSocketHandle()
- constructor */
+ address.
+
+ \param[in] address remote address to connect to */
+ /**< \note This member is implicitly called from the
+ ProtocolClientSocketHandle::ProtocolClientSocketHandle()
+ constructor */
void init_server() const; ///< Create server socket
- /**< \note This member is implicitly called from the
- ProtocolServerSocketHandle::ProtocolServerSocketHandle()
- constructor */
+ /**< \note This member is implicitly called from the
+ ProtocolServerSocketHandle::ProtocolServerSocketHandle()
+ constructor */
void init_server(INet4Address const & address, unsigned backlog=1) const;
///< Create server socket and listen
/**< Creates a new server socket, binds to \a address end
- starts listening for new connections with a backlog of
- \a backlog connections. It also enables reuseaddr().
+ starts listening for new connections with a backlog of
+ \a backlog connections. It also enables reuseaddr().
- \param[in] address address to listen on
- \param[in] backlog size of the listen backlog */
- /**< \note This member is implicitly called from the
- ProtocolServerSocketHandle::ProtocolServerSocketHandle()
- constructor */
+ \param[in] address address to listen on
+ \param[in] backlog size of the listen backlog */
+ /**< \note This member is implicitly called from the
+ ProtocolServerSocketHandle::ProtocolServerSocketHandle()
+ constructor */
- ///@}
- ///\name Abstract Interface Implementation
+ ///@}
+ ///\name Abstract Interface Implementation
std::auto_ptr<SocketProtocol> clone() const;
-
- ///@}
+
+ ///@}
};
typedef ProtocolClientSocketHandle<TCPv4SocketProtocol> TCPv4ClientSocketHandle;
>::policy TCPv6Socket_Policy;
/** \brief IPv6 TCP Socket Protocol
-
- \par Socket Handle typedefs:
- \ref TCPv6ClientSocketHandle (ProtocolClientSocketHandle), \ref TCPv6ServerSocketHandle
- (ProtocolServerSocketHandle)
-
- \par Protocol Interface:
- ClientSocketHandle::read(), ClientSocketHandle::write(), ClientSocketHandle::bind(),
- ClientSocketHandle::local(), ClientSocketHandle::connect(), ClientSocketHandle::peer(),
- ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf()
-
- \par Address Type:
- INet6Address
-
- TCPv6SocketProtocol provides an internet protocol stream socket based on the TCP protocol
- and IPv6 addressing.
-
- This class is utilized as the protocol class of the ProtocolClientSocketHandle and
- ProtocolServerSocketHandle via the Socket Handle typedefs above.
-
- \see TCPv4SocketProtocol
+
+ \par Socket Handle typedefs:
+ \ref TCPv6ClientSocketHandle (ProtocolClientSocketHandle), \ref TCPv6ServerSocketHandle
+ (ProtocolServerSocketHandle)
+
+ \par Protocol Interface:
+ ClientSocketHandle::read(), ClientSocketHandle::write(), ClientSocketHandle::bind(),
+ ClientSocketHandle::local(), ClientSocketHandle::connect(), ClientSocketHandle::peer(),
+ ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf()
+
+ \par Address Type:
+ INet6Address
+
+ TCPv6SocketProtocol provides an internet protocol stream socket based on the TCP protocol
+ and IPv6 addressing.
+
+ This class is utilized as the protocol class of the ProtocolClientSocketHandle and
+ ProtocolServerSocketHandle via the Socket Handle typedefs above.
+
+ \see TCPv4SocketProtocol
*/
class TCPv6SocketProtocol
- : public ConcreteSocketProtocol<TCPv6Socket_Policy>,
+ : public ConcreteSocketProtocol<TCPv6Socket_Policy>,
public IPv6Protocol,
public TCPProtocol,
public BSDSocketProtocol,
///////////////////////////////////////////////////////////////////////////
// internal interface
- ///\name Constructors
- ///@{
+ ///\name Constructors
+ ///@{
void init_client() const; ///< Create unconnected client socket
- /**< \note This member is implicitly called from the
- ProtocolClientSocketHandle::ProtocolClientSocketHandle()
- constructor */
+ /**< \note This member is implicitly called from the
+ ProtocolClientSocketHandle::ProtocolClientSocketHandle()
+ constructor */
void init_client(INet6SocketAddress const & address) const;
///< Create client socket and connect
/**< Creates a new client socket and connects to the given
- address.
-
- \param[in] address remote address to connect to */
- /**< \note This member is implicitly called from the
- ProtocolClientSocketHandle::ProtocolClientSocketHandle()
- constructor */
+ address.
+
+ \param[in] address remote address to connect to */
+ /**< \note This member is implicitly called from the
+ ProtocolClientSocketHandle::ProtocolClientSocketHandle()
+ constructor */
void init_server() const; ///< Create server socket
- /**< \note This member is implicitly called from the
- ProtocolServerSocketHandle::ProtocolServerSocketHandle()
- constructor */
+ /**< \note This member is implicitly called from the
+ ProtocolServerSocketHandle::ProtocolServerSocketHandle()
+ constructor */
void init_server(INet6SocketAddress const & address, unsigned backlog=1) const;
///< Create server socket and listen
/**< Creates a new server socket, binds to \a address end
- starts listening for new connections with a backlog of
- \a backlog connections. It also enables reuseaddr().
+ starts listening for new connections with a backlog of
+ \a backlog connections. It also enables reuseaddr().
- \param[in] address address to listen on
- \param[in] backlog size of the listen backlog */
- /**< \note This member is implicitly called from the
- ProtocolServerSocketHandle::ProtocolServerSocketHandle()
- constructor */
+ \param[in] address address to listen on
+ \param[in] backlog size of the listen backlog */
+ /**< \note This member is implicitly called from the
+ ProtocolServerSocketHandle::ProtocolServerSocketHandle()
+ constructor */
- ///@}
- ///\name Abstract Interface Implementation
+ ///@}
+ ///\name Abstract Interface Implementation
std::auto_ptr<SocketProtocol> clone() const;
-
- ///@}
+
+ ///@}
};
typedef ProtocolClientSocketHandle<TCPv6SocketProtocol> TCPv6ClientSocketHandle;
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
void stop()
{
- if (server_pid) {
- kill(server_pid,9);
- wait();
- server_pid = 0;
- }
+ if (server_pid) {
+ kill(server_pid,9);
+ wait();
+ server_pid = 0;
+ }
}
}
if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
fail("server_v4","setsockopt()");
struct sockaddr_in sin;
- ::memset(&sin,0,sizeof(sin));
+ ::memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(12345);
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
fail("server_v6","setsockopt()");
struct sockaddr_in6 sin;
- ::memset(&sin,0,sizeof(sin));
+ ::memset(&sin,0,sizeof(sin));
sin.sin6_family = AF_INET6;
sin.sin6_port = htons(12345);
sin.sin6_addr = in6addr_loopback;
}
try {
- alarm(10);
+ alarm(10);
start(server_v4);
senf::TCPv4ClientSocketHandle sock;
BOOST_CHECK_NO_THROW( sock.bind("127.0.0.1:23456") );
BOOST_CHECK_EQUAL( sock.read(), "" );
BOOST_CHECK( sock.eof() );
BOOST_CHECK( !sock );
- alarm(0);
+ alarm(0);
} catch (...) {
- alarm(0);
- sleep(1);
- stop();
- sleep(1);
- throw;
+ alarm(0);
+ sleep(1);
+ stop();
+ sleep(1);
+ throw;
}
-
+
{
senf::TCPv4ClientSocketHandle sock;
BOOST_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0","127.0.0.1:0") );
BOOST_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0") );
BOOST_CHECK_THROW( sock.protocol().mcIface("lo"), senf::SystemException );
-
+
// The following setsockopts are hard to REALLY test ...
BOOST_CHECK_NO_THROW( sock.protocol().nodelay(true) );
BOOST_CHECK( sock.protocol().nodelay() );
}
try {
- alarm(10);
+ alarm(10);
start(server_v6);
senf::TCPv6ClientSocketHandle sock;
BOOST_CHECK_NO_THROW( sock.bind("[::1]:23456") );
BOOST_CHECK_EQUAL( sock.read(), "" );
BOOST_CHECK( sock.eof() );
BOOST_CHECK( !sock );
- alarm(0);
+ alarm(0);
} catch (...) {
- alarm(0);
- sleep(1);
- stop();
- sleep(1);
- throw;
+ alarm(0);
+ sleep(1);
+ stop();
+ sleep(1);
+ throw;
}
-
+
{
senf::TCPv6ClientSocketHandle sock;
int sock = socket(PF_INET,SOCK_STREAM,0);
if (sock<0) fail("client_v4","socket()");
struct sockaddr_in sin;
- ::memset(&sin,0,sizeof(sin));
+ ::memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(12346);
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
fail("client_v4","connect()");
-
+
char buffer[1024];
while (1) {
int n = read(sock,buffer,1024);
int sock = socket(PF_INET6,SOCK_STREAM,0);
if (sock<0) fail("client_v6","socket()");
struct sockaddr_in6 sin;
- ::memset(&sin,0,sizeof(sin));
+ ::memset(&sin,0,sizeof(sin));
sin.sin6_family = AF_INET6;
sin.sin6_port = htons(12347);
sin.sin6_addr = in6addr_loopback;
if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
fail("client_v6","connect()");
-
+
char buffer[1024];
while (1) {
int n = read(sock,buffer,1024);
BOOST_AUTO_UNIT_TEST(tcpv4ServerSocketHandle)
{
try {
- alarm(10);
+ alarm(10);
BOOST_CHECKPOINT("Opening server socket");
senf::TCPv4ServerSocketHandle server ("127.0.0.1:12346");
BOOST_CHECKPOINT("Starting client");
BOOST_CHECKPOINT("Stopping client");
sleep(1);
stop();
- alarm(0);
+ alarm(0);
} catch (...) {
- alarm(0);
- sleep(1);
- stop();
- sleep(1);
- throw;
+ alarm(0);
+ sleep(1);
+ stop();
+ sleep(1);
+ throw;
}
}
BOOST_AUTO_UNIT_TEST(tcpv6ServerSocketHandle)
{
try {
- alarm(10);
+ alarm(10);
BOOST_CHECKPOINT("Opening server socket");
senf::TCPv6ServerSocketHandle server ("[::1]:12347");
BOOST_CHECKPOINT("Starting client");
BOOST_CHECKPOINT("Stopping client");
sleep(1);
stop();
- alarm(0);
+ alarm(0);
} catch (...) {
- alarm(0);
- sleep(1);
- stop();
- sleep(1);
- throw;
+ alarm(0);
+ sleep(1);
+ stop();
+ sleep(1);
+ throw;
}
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id: main.test.cc 32 2006-03-23 16:24:56Z sbund $
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
{
int pid = fork();
if (pid < 0)
- throw senf::SystemException("fork",errno);
+ throw senf::SystemException("fork",errno);
if (pid > 0)
- ::_exit(0);
+ ::_exit(0);
if (::setsid() < 0)
- throw senf::SystemException("setsid",errno);
+ throw senf::SystemException("setsid",errno);
}
prefix_ void senf::redirect_stdio(std::string const & path)
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
This collection of utilities provides help in managing daemon processes.
\idea Add communication between parent and child process to daemonize() and add things like
- init_done(), failure() etc which allow the daemon process to tell the frontend of successful
- startup or failure. This proabably means moving all the methods into a DaemonTools class (as
- statics or via a singleton). This would also allow for automatic pid file creation and
- removal (remove in global destructor).
+ init_done(), failure() etc which allow the daemon process to tell the frontend of successful
+ startup or failure. This proabably means moving all the methods into a DaemonTools class (as
+ statics or via a singleton). This would also allow for automatic pid file creation and
+ removal (remove in global destructor).
\idea Add a DaemonProcess baseclass whith init() and main() abstract members which wraps the
- startup process. DaeminProcess::run() would fork, call init(), create a pid file and then
- call main(). Exceptions during init()'s execution would be passed to the parent
- process. This is based on the above API.
-
+ startup process. DaeminProcess::run() would fork, call init(), create a pid file and then
+ call main(). Exceptions during init()'s execution would be passed to the parent
+ process. This is based on the above API.
+
\idea A closeall()/closemost() function which is useful when starting child processes. We'll use
- getrlimit to now the biggest filehandle and close all of em. closemost() takes a number of
- file handles as arg and will keep those open.
+ getrlimit to now the biggest filehandle and close all of em. closemost() takes a number of
+ file handles as arg and will keep those open.
\idea We might want to add other oft used utitlities: chroot(), setreuid(), pipes() / IPC ...
*/
void daemonize(); ///< Make the current process a daemon process
/**< daemonize() will fork, detach from the controlling
- terminal and start a new process group. */
+ terminal and start a new process group. */
void redirect_stdio(std::string const & path = "/dev/null"); ///< Redirect STDIN, STDOUT and STDERR
/**< All standard file-descriptors will be redirected to the
- given path defaulting to <tt>/dev/null</tg>
- \param[in] path path to redirect to */
+ given path defaulting to <tt>/dev/null</tg>
+ \param[in] path path to redirect to */
/// @}
}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
///////////////////////////////cci.p///////////////////////////////////////
prefix_ senf::SystemException::SystemException(int err_)
- : where(0), err(err_)
+ : where(0), err(err_)
{
- init();
+ init();
}
prefix_ senf::SystemException::SystemException(char const * where_, int err_)
- : where(where_), err(err_)
-{
- init();
+ : where(where_), err(err_)
+{
+ init();
}
prefix_ senf::SystemException::~SystemException()
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief Exception handling standard UNIX errors (errno)
- This exception is thrown to signal generic errno failuers.
+ This exception is thrown to signal generic errno failuers.
- \todo make where and err accessors and make the member vars private
+ \todo make where and err accessors and make the member vars private
- \idea Add a template class derived from SystemException which
- takes the error number as a numeric argument. This allows
- catching specific errno conditions: ErrnoException<EPIPE> etc.
-
- \idea Add a generic error thrower which takes the origin
- string and errno value as an argument and will throw a
- corresponding template class instance. This would just be a
- big switch statement containing all possible errno values,
- probably created using some makro metaprogramming.
+ \idea Add a template class derived from SystemException which
+ takes the error number as a numeric argument. This allows
+ catching specific errno conditions: ErrnoException<EPIPE> etc.
+
+ \idea Add a generic error thrower which takes the origin
+ string and errno value as an argument and will throw a
+ corresponding template class instance. This would just be a
+ big switch statement containing all possible errno values,
+ probably created using some makro metaprogramming.
*/
class SystemException : public std::exception
{
/**< \param[in] err errror number (the errno value) */
SystemException(char const * where, int err); ///< SystemException with error lokus info
/**< \param[in] where description of error origin
- \param[in] err error number (the errno value) */
+ \param[in] err error number (the errno value) */
virtual char const * what() const throw(); ///< Return verbose error description
virtual ~SystemException() throw();
private:
void init();
- std::string buffer_;
+ std::string buffer_;
};
-
+
}
///////////////////////////////hh.e////////////////////////////////////////
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
\brief Logger public header */
/** \defgroup logger The SENF Logger
-
+
The Loggger infrastructure shall implement a highliy flexible compile- and run-time configurable
logging infrastructure supporting multiple streams, user defineable log areas and fine grained
log levels. Logging can be configured at compile and runtime on any combination of above
arguments are encoded into a <a
href="http://www.boost.org/libs/preprocessor/doc/index.html">Boost.Preprocessor</a> like
sequence:
-
+
\code
SENF_LOG( (senf::log::Debug)(senf::log::NOTICE)(FroblizerArea)("The log message") );
\endcode
-
+
The last sequence element always is the log message. Before that we have a number of log
parameters <it>in arbitrary order</it>. Since giving all the parameters in every log message is
to verbose, there are two helpful constructs to reduce the verbosity. Using \ref SENF_LOG_DEFAULTS it
\code
SENF_LOG_DEF_STREAM(userLog);
-
- class Froblizer
+
+ class Froblizer
{
// Define a new log area
SENF_LOG_DEF_AREA(FroblizerArea);
# ifndef _senf_LOG_STREAM
# define _senf_LOG_STREAM std::cerr
# endif
-
+
/// \addtogroup logger
/// @{
/** \brief Write log message
-
- This macro will write it's last argument to the log stream. The last argument must be an
- expression which will be placed after a streaming \c operator<< (like
- <it>some-log-sttream</it> \c << <it>last-macro-arg</it>).
- \code
- BOOST_LOG((parameters...)("log message " << args << ...));
- \endcode
-
- \hideinitializer
+
+ This macro will write it's last argument to the log stream. The last argument must be an
+ expression which will be placed after a streaming \c operator<< (like
+ <it>some-log-sttream</it> \c << <it>last-macro-arg</it>).
+ \code
+ BOOST_LOG((parameters...)("log message " << args << ...));
+ \endcode
+
+ \hideinitializer
*/
-# define SENF_LOG(args) \
- _senf_LOG_STREAM << BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args) \
+# define SENF_LOG(args) \
+ _senf_LOG_STREAM << BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args) \
<< std::endl;
/** \brief Enable block based on logging parameters
-
- This macro is like SENF_LOG, however instead of writing a simple message, this macro allows
- to specify a complete block of code to be executed if the log message is enabled.
- \code
- BOOST_LOG_BLOCK((parameters...)({
- // arbitrary code using 'log' for logging
- log << "log message";
+
+ This macro is like SENF_LOG, however instead of writing a simple message, this macro allows
+ to specify a complete block of code to be executed if the log message is enabled.
+ \code
+ BOOST_LOG_BLOCK((parameters...)({
+ // arbitrary code using 'log' for logging
+ log << "log message";
}));
- \endcode
+ \endcode
- \hideinitializer
+ \hideinitializer
*/
-# define SENF_LOG_BLOCK(args) \
- do { \
- std::ostream & log (_senf_LOG_STREAM); \
- BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args) \
- log << std::endl; \
- } while (0)
+# define SENF_LOG_BLOCK(args) \
+ do { \
+ std::ostream & log (_senf_LOG_STREAM); \
+ BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args) \
+ log << std::endl; \
+ } while (0)
/** \brief Set scope default log parameters
- Sets the default log parameters for the current scope
- \code
- BOOST_LOG_DEFAULTS((parameters...));
- \endcode
+ Sets the default log parameters for the current scope
+ \code
+ BOOST_LOG_DEFAULTS((parameters...));
+ \endcode
- \hideinitializer
+ \hideinitializer
*/
# define SENF_LOG_DEFAULTS(args)
/** \brief Define log area
-
- Defines a new log area named \a area. The area is defined as a symbol in the current scope.
- \hideinitializer
+ Defines a new log area named \a area. The area is defined as a symbol in the current scope.
+
+ \hideinitializer
*/
# define SENF_LOG_DEF_AREA(area)
/** \brief Define log stream
-
- Defines a new log stream named \a stream. The stream is defined as a symbol in the current
- scope.
- \hideinitializer
+ Defines a new log stream named \a stream. The stream is defined as a symbol in the current
+ scope.
+
+ \hideinitializer
*/
# define SENF_LOG_DEF_STREAM(stream)
/** \brief Define log parameter alias
-
- Defines a new parameter alias named \a alias as an alias for the parameters in \a args. The
- alias is defined as a symbol in the current scope.
- \hideinitializer
+ Defines a new parameter alias named \a alias as an alias for the parameters in \a args. The
+ alias is defined as a symbol in the current scope.
+
+ \hideinitializer
*/
# define SENF_LOG_DEF_ALIAS(alias,args)
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
SENF_LOG((LogFoo) ("Another log message: " << 10));
SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
- log << "Last message";
- log << " continued here";
+ log << "Last message";
+ log << " continued here";
}));
BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// End:
<dt>\ref time</dt><dd>Very rudimentary microsecond time
support</dd>
-
+
<dt>\ref process</dt><dd>Some simple process management and daemon
helpers<?dd>
-
+
<dt>\ref membind</dt><dd>a simple <a
href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a>
extension</dd>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// mode: flyspell
// mode: auto-fill
-// ispell-local-dictionary: "american"
// End:
{
struct timeval tv;
if (gettimeofday(&tv,0) < 0)
- throw SystemException(errno);
+ throw SystemException(errno);
return 1000000*MicroTime(tv.tv_sec) + tv.tv_usec;
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
supported members are the datatype (which just uses a 64 bit
integer) and the now() function to get the current UTC time in
microsecods since the Epoch.
-
+
\idea This thing only exists as a quick hack. We can probably make
- use of Boost.Time or some such thing so it probably does not
- make sense to extend this further. We should however check the
- performance of Boost.Time since this is used heavily in the
- Scheduler.
+ use of Boost.Time or some such thing so it probably does not
+ make sense to extend this further. We should however check the
+ performance of Boost.Time since this is used heavily in the
+ Scheduler.
*/
#ifndef HH_MicroTime_
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
-
+
/// \addtogroup time
/// @{
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Unit tests
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Definition of inline non-template functions
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Definition of inline template functions
const
{
return (static_cast<const T*>(this))->boolean_test()
- ? &SafeBoolBase::this_type_does_not_support_comparisons : 0;
+ ? &SafeBoolBase::this_type_does_not_support_comparisons : 0;
}
template <typename T>
template <typename T, typename U>
prefix_ void senf::operator==(const SafeBool<T>& lhs, const SafeBool<U>& rhs)
{
- lhs.this_type_does_not_support_comparisons();
+ lhs.this_type_does_not_support_comparisons();
}
template <typename T, typename U>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
#ifndef HH_SafeBool_
#define HH_SafeBool_ 1
namespace senf {
/** \brief internal SafeBool base class
- \internal
+ \internal
*/
- class SafeBoolBase
+ class SafeBoolBase
{
protected:
- typedef void (SafeBoolBase::*bool_type)() const;
- void this_type_does_not_support_comparisons() const;
+ typedef void (SafeBoolBase::*bool_type)() const;
+ void this_type_does_not_support_comparisons() const;
- // Just here to make them protected ...
+ // Just here to make them protected ...
- SafeBoolBase();
- SafeBoolBase(const SafeBoolBase&);
- SafeBoolBase& operator=(const SafeBoolBase&);
- ~SafeBoolBase();
+ SafeBoolBase();
+ SafeBoolBase(const SafeBoolBase&);
+ SafeBoolBase& operator=(const SafeBoolBase&);
+ ~SafeBoolBase();
};
/** \brief Mixin class for safe boolean conversion support
-
- This is a direct yet simplified copy of a safe bool solution
- by Bjorn Karlsson from
- http://www.artima.com/cppsource/safebool.html
-
- This mixin provides the client class with safe boolean
- testing. It is a safe replacement for <tt>operator
- bool</tt>. <tt>operator bool</tt> is problematic since \c bool
- is an integer type. This conversion operator makes the class
- usable in any numeric context, which can be quite
- dangerous. The <tt>operator void *</tt> solution is much
- better in this respect but still allows two instances of any
- class having such a <tt>void *</tt> conversion to be compared
- for equality. This again will produce absolutely unexpected
- results since it will not check wethere the objects are
- identical, it will only check, that both return the same
- boolean state.
-
- This solutions solves all these problems by returning a
- pointer-to-member which cannot be converted to any other
- type. By providing explicit implementations of \c operator==
- and \c operator!= which fail in an obvious way at compile
- time, this hazard is removed.
-
- To make a class boolean testable, just inherit from the mixin
- and implement \c boolean_test:
-
- \code
- class Testable
- : public SafeBool<Testable>
+
+ This is a direct yet simplified copy of a safe bool solution
+ by Bjorn Karlsson from
+ http://www.artima.com/cppsource/safebool.html
+
+ This mixin provides the client class with safe boolean
+ testing. It is a safe replacement for <tt>operator
+ bool</tt>. <tt>operator bool</tt> is problematic since \c bool
+ is an integer type. This conversion operator makes the class
+ usable in any numeric context, which can be quite
+ dangerous. The <tt>operator void *</tt> solution is much
+ better in this respect but still allows two instances of any
+ class having such a <tt>void *</tt> conversion to be compared
+ for equality. This again will produce absolutely unexpected
+ results since it will not check wethere the objects are
+ identical, it will only check, that both return the same
+ boolean state.
+
+ This solutions solves all these problems by returning a
+ pointer-to-member which cannot be converted to any other
+ type. By providing explicit implementations of \c operator==
+ and \c operator!= which fail in an obvious way at compile
+ time, this hazard is removed.
+
+ To make a class boolean testable, just inherit from the mixin
+ and implement \c boolean_test:
+
+ \code
+ class Testable
+ : public SafeBool<Testable>
{
public:
- bool boolean_test() const
+ bool boolean_test() const
{
// Perform Boolean logic here
}
};
- Testable t = ...;
+ Testable t = ...;
- if (t) {
- ...
- }
- \endcode
+ if (t) {
+ ...
+ }
+ \endcode
- \todo Either rename intrusive_refcount to IntrusiveRefcount or
- SafeBool to safe_bool (I tend to the latter ...)
+ \todo Either rename intrusive_refcount to IntrusiveRefcount or
+ SafeBool to safe_bool (I tend to the latter ...)
*/
- template <typename T>
- class SafeBool
- : public SafeBoolBase
+ template <typename T>
+ class SafeBool
+ : public SafeBoolBase
{
public:
- operator bool_type() const;
- bool operator !() const;
+ operator bool_type() const;
+ bool operator !() const;
protected:
- ~SafeBool();
+ ~SafeBool();
};
- template <typename T, typename U>
+ template <typename T, typename U>
void operator==(const SafeBool<T>& lhs,const SafeBool<U>& rhs);
- template <typename T,typename U>
+ template <typename T,typename U>
void operator!=(const SafeBool<T>& lhs,const SafeBool<U>& rhs);
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cc.p////////////////////////////////////////
-// WARNING: This is completely g++ and libiberty dependent. The demangling
-// interface isn't even explicitly exportet from libiberty. However, it is
+// WARNING: This is completely g++ and libiberty dependent. The demangling
+// interface isn't even explicitly exportet from libiberty. However, it is
// *EXTREMELY* helpful for debugging ...
prefix_ std::string senf::prettyName(std::type_info const & type)
char const * mangled = type.name();
char * demangled = ::cplus_demangle(mangled,DMGL_TYPES|DMGL_AUTO);
std::string name (demangled ? demangled : mangled);
- if (demangled)
+ if (demangled)
::free(demangled);
return name;
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
namespace senf {
/** \brief Try to return readable type for given type_info
-
- This function will try to return a demangled type name for the
- given type_info object. If the demangling fails, the possibly
- mangled name (type->name()) will be returned.
- This function depends on the liberty library provided by the
- linux binutils or binutils-dev packages. It also depends on an
- internal header file. If the API should change, this header
- file (which resides in impl/demangle.h) must be updated from
- the binutils sources.
+ This function will try to return a demangled type name for the
+ given type_info object. If the demangling fails, the possibly
+ mangled name (type->name()) will be returned.
- \param[in] type type_info object
- \returns type name, possibly demangled
+ This function depends on the liberty library provided by the
+ linux binutils or binutils-dev packages. It also depends on an
+ internal header file. If the API should change, this header
+ file (which resides in impl/demangle.h) must be updated from
+ the binutils sources.
+
+ \param[in] type type_info object
+ \returns type name, possibly demangled
*/
std::string prettyName(std::type_info const & type);
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cc.p////////////////////////////////////////
namespace test {
-
+
struct Base {
virtual ~Base() {}
};
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
/* Defs for interface to demanglers.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
2003, 2004 Free Software Foundation, Inc.
-
+
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, or (at your option)
/* Options passed to cplus_demangle (in 2nd parameter). */
-#define DMGL_NO_OPTS 0 /* For readability... */
-#define DMGL_PARAMS (1 << 0) /* Include function args */
-#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
-#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
-#define DMGL_VERBOSE (1 << 3) /* Include implementation details. */
-#define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */
-
-#define DMGL_AUTO (1 << 8)
-#define DMGL_GNU (1 << 9)
-#define DMGL_LUCID (1 << 10)
-#define DMGL_ARM (1 << 11)
-#define DMGL_HP (1 << 12) /* For the HP aCC compiler;
+#define DMGL_NO_OPTS 0 /* For readability... */
+#define DMGL_PARAMS (1 << 0) /* Include function args */
+#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
+#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
+#define DMGL_VERBOSE (1 << 3) /* Include implementation details. */
+#define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */
+
+#define DMGL_AUTO (1 << 8)
+#define DMGL_GNU (1 << 9)
+#define DMGL_LUCID (1 << 10)
+#define DMGL_ARM (1 << 11)
+#define DMGL_HP (1 << 12) /* For the HP aCC compiler;
same as ARM except for
template arguments, etc. */
-#define DMGL_EDG (1 << 13)
-#define DMGL_GNU_V3 (1 << 14)
-#define DMGL_GNAT (1 << 15)
+#define DMGL_EDG (1 << 13)
+#define DMGL_GNU_V3 (1 << 14)
+#define DMGL_GNAT (1 << 15)
/* If none of these are set, use 'current_demangling_style' as the default. */
#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT)
/* Define string names for the various demangling styles. */
#define NO_DEMANGLING_STYLE_STRING "none"
-#define AUTO_DEMANGLING_STYLE_STRING "auto"
-#define GNU_DEMANGLING_STYLE_STRING "gnu"
-#define LUCID_DEMANGLING_STYLE_STRING "lucid"
-#define ARM_DEMANGLING_STYLE_STRING "arm"
-#define HP_DEMANGLING_STYLE_STRING "hp"
-#define EDG_DEMANGLING_STYLE_STRING "edg"
+#define AUTO_DEMANGLING_STYLE_STRING "auto"
+#define GNU_DEMANGLING_STYLE_STRING "gnu"
+#define LUCID_DEMANGLING_STYLE_STRING "lucid"
+#define ARM_DEMANGLING_STYLE_STRING "arm"
+#define HP_DEMANGLING_STYLE_STRING "hp"
+#define EDG_DEMANGLING_STYLE_STRING "edg"
#define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3"
#define JAVA_DEMANGLING_STYLE_STRING "java"
#define GNAT_DEMANGLING_STYLE_STRING "gnat"
extern void
set_cplus_marker_for_demangling PARAMS ((int ch));
-extern enum demangling_styles
+extern enum demangling_styles
cplus_demangle_set_style PARAMS ((enum demangling_styles style));
-extern enum demangling_styles
+extern enum demangling_styles
cplus_demangle_name_to_style PARAMS ((const char *name));
/* V3 ABI demangling entry points, defined in cp-demangle.c. */
gnu_v3_ctor_kinds' value indicating what kind of constructor
it is. */
extern enum gnu_v3_ctor_kinds
- is_gnu_v3_mangled_ctor PARAMS ((const char *name));
+ is_gnu_v3_mangled_ctor PARAMS ((const char *name));
enum gnu_v3_dtor_kinds {
gnu_v3_dtor_kinds' value, indicating what kind of destructor
it is. */
extern enum gnu_v3_dtor_kinds
- is_gnu_v3_mangled_dtor PARAMS ((const char *name));
+ is_gnu_v3_mangled_dtor PARAMS ((const char *name));
/* The V3 demangler works in two passes. The first pass builds a tree
representation of the mangled name, and the second pass turns the
struct
{
/* A pointer to the name (which need not NULL terminated) and
- its length. */
+ its length. */
const char *s;
int len;
} s_name;
extern int
cplus_demangle_fill_component PARAMS ((struct demangle_component *fill,
- enum demangle_component_type,
- struct demangle_component *left,
- struct demangle_component *right));
+ enum demangle_component_type,
+ struct demangle_component *left,
+ struct demangle_component *right));
/* Fill in a DEMANGLE_COMPONENT_NAME. Returns non-zero on success,
zero for bad arguments. */
extern int
cplus_demangle_fill_name PARAMS ((struct demangle_component *fill,
- const char *, int));
+ const char *, int));
/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the
builtin type (e.g., "int", etc.). Returns non-zero on success,
extern int
cplus_demangle_fill_builtin_type PARAMS ((struct demangle_component *fill,
- const char *type_name));
+ const char *type_name));
/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the
operator and the number of arguments which it takes (the latter is
extern int
cplus_demangle_fill_operator PARAMS ((struct demangle_component *fill,
- const char *opname, int args));
+ const char *opname, int args));
/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the
number of arguments and the name. Returns non-zero on success,
extern int
cplus_demangle_fill_extended_operator PARAMS ((struct demangle_component *fill,
- int numargs,
- struct demangle_component *nm));
+ int numargs,
+ struct demangle_component *nm));
/* Fill in a DEMANGLE_COMPONENT_CTOR. Returns non-zero on success,
zero for bad arguments. */
extern int
cplus_demangle_fill_ctor PARAMS ((struct demangle_component *fill,
- enum gnu_v3_ctor_kinds kind,
- struct demangle_component *name));
+ enum gnu_v3_ctor_kinds kind,
+ struct demangle_component *name));
/* Fill in a DEMANGLE_COMPONENT_DTOR. Returns non-zero on success,
zero for bad arguments. */
extern int
cplus_demangle_fill_dtor PARAMS ((struct demangle_component *fill,
- enum gnu_v3_dtor_kinds kind,
- struct demangle_component *name));
+ enum gnu_v3_dtor_kinds kind,
+ struct demangle_component *name));
/* This function translates a mangled name into a struct
demangle_component tree. The first argument is the mangled name.
extern struct demangle_component *
cplus_demangle_v3_components PARAMS ((const char *mangled,
- int options,
- void **mem));
+ int options,
+ void **mem));
/* This function takes a struct demangle_component tree and returns
the corresponding demangled string. The first argument is DMGL_*
extern char *
cplus_demangle_print PARAMS ((int options,
- const struct demangle_component *tree,
- int estimated_length,
- size_t *p_allocated_size));
+ const struct demangle_component *tree,
+ int estimated_length,
+ size_t *p_allocated_size));
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#endif /* DEMANGLE_H */
+#endif /* DEMANGLE_H */
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
#define scARG(z,n,d) BOOST_PP_CAT(d,n)
#define scPARAMS(d) BOOST_PP_ENUM_SHIFTED(BOOST_PP_ITERATION(),scARG,d)
-
+
template < typename R, typename T, scPARAMS(typename A) >
-boost::function<R ( scPARAMS(A) )>
+boost::function<R ( scPARAMS(A) )>
membind(R (T::* fn)( scPARAMS(A) ), scOBTYPE ob)
{
return boost::bind(fn, ob, scPARAMS(_) );
#undef scPARAMS
#undef scARG
-
+
// }
#endif
// done
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
/** \brief Reference count mixin for intrusive_ptr
- This class provides a simple internally managed refcount and supplies the <a
- href="http://www.boost.org/libs/smart_ptr/intrusive_ptr.html">boost::intrusive_ptr</a>
- required interface. To make a class compatible with \c boost::intrusive_ptr, just derive
- publicly from intrusive_refcount.
+ This class provides a simple internally managed refcount and supplies the <a
+ href="http://www.boost.org/libs/smart_ptr/intrusive_ptr.html">boost::intrusive_ptr</a>
+ required interface. To make a class compatible with \c boost::intrusive_ptr, just derive
+ publicly from intrusive_refcount.
- Two additional benifits of using intrusive_refcount are
- \li The object can access it's own refcount
- \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time
- (not only after new)
+ Two additional benifits of using intrusive_refcount are
+ \li The object can access it's own refcount
+ \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time
+ (not only after new)
*/
class intrusive_refcount
: public boost::noncopyable
protected:
intrusive_refcount();
-
+
private:
void add_ref();
bool release();
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- struct Tester
+ struct Tester
: public senf::intrusive_refcount
{
typedef boost::intrusive_ptr<Tester> ptr;
BOOST_CHECK_EQUAL(p->refcount(),2u);
BOOST_CHECK_EQUAL(p->is_shared(),true);
}
-
+
BOOST_CHECK_EQUAL(Tester::counter,1u);
BOOST_CHECK_EQUAL(p->refcount(),1u);
BOOST_CHECK_EQUAL(p->is_shared(),false);
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id: main.test.cc 32 2006-03-23 16:24:56Z sbund $
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
int test(int x);
};
- Foo * foo = ...;
+ Foo * foo = ...;
boost::function<int (int)> f = senf::membind(&Foo::test,foo);
int rv = f(1); // Calls foo->test(1)
\endcode
/** \brief Build bound member function object
- membind() supports up to 9 function parameters (represented as
- \a Args here). The \a ob argument can be either a pointer or a
- reference to \a T
- \param[in] fn member function pointer
- \param[in] ob object instance to bind this pointer to
- \returns Boost.Function object representing a bound call of \a
- fn on \a ob
+ membind() supports up to 9 function parameters (represented as
+ \a Args here). The \a ob argument can be either a pointer or a
+ reference to \a T
+ \param[in] fn member function pointer
+ \param[in] ob object instance to bind this pointer to
+ \returns Boost.Function object representing a bound call of \a
+ fn on \a ob
*/
template <typename R, typename T, typename Args>
boost::function<R (Args)> membind(R (T::* fn)( Args ), T * ob);
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
///////////////////////////////cc.p////////////////////////////////////////
namespace {
-
+
struct Test {
- char const * meth1() {
+ char const * meth1() {
return "meth1()";
}
\f
// Local Variables:
// mode: c++
+// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End:
INPUT_FILTER = "$(TOPDIR)/doclib/filter.pl"
ALIASES = "fixme=\xrefitem fixme \"Fix\" \"Fixmes\"" \
- "idea=\xrefitem idea \"Idea\" \"Ideas\"" \
- "implementation=\par \"Implementation note:\""
+ "idea=\xrefitem idea \"Idea\" \"Ideas\"" \
+ "implementation=\par \"Implementation note:\""
REPEAT_BRIEF = YES
ALWAYS_DETAILED_SEC = YES
MULTILINE_CPP_IS_BRIEF = YES
<div class="tabs">
<ul>
- <li><a href="xref.html">Open Issues</a></li>
- <li><a class="ext" href="http://svn.berlios.de/wsvn/senf/?op=log&rev=0&sc=0&isdir=1">SVN ChangeLog</a></li>
+ <li><a href="xref.html">Open Issues</a></li>
+ <li><a class="ext" href="http://svn.berlios.de/wsvn/senf/?op=log&rev=0&sc=0&isdir=1">SVN ChangeLog</a></li>
<li><a class="ext" href="http://developer.berlios.de/projects/senf">SENF @ BerliOS</a></li>
- <li><a class="ext" href="http://openfacts.berlios.de/index-en.phtml?title=SENF+Network+Framework">Wiki</a></li>
+ <li><a class="ext" href="http://openfacts.berlios.de/index-en.phtml?title=SENF+Network+Framework">Wiki</a></li>
</ul>
</div>
\ No newline at end of file
body {
- padding: 0;
- margin: 0;
- font-family: Verdana, Arial, Helvetica, sans-serif;
+ padding: 0;
+ margin: 0;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
}
#head {
- height: 62px;
- border-top: 5px solid #DECD40;
- border-bottom: 1px solid #AF9D00;
- background: url(logo-head.png) top left no-repeat;
- background-color: #EDE497;
+ height: 62px;
+ border-top: 5px solid #DECD40;
+ border-bottom: 1px solid #AF9D00;
+ background: url(logo-head.png) top left no-repeat;
+ background-color: #EDE497;
}
#head h1 {
- margin: 0 0 0 100px;
- padding: 6px 0 0 42px;
- height: 33px;
- background-color: #DECD40;
- border-bottom: 1px solid #AF9D00;
- font-size: 22px;
- font-weight: bold;
- color: white;
- white-space: nowrap;
- text-align: left;
+ margin: 0 0 0 100px;
+ padding: 6px 0 0 42px;
+ height: 33px;
+ background-color: #DECD40;
+ border-bottom: 1px solid #AF9D00;
+ font-size: 22px;
+ font-weight: bold;
+ color: white;
+ white-space: nowrap;
+ text-align: left;
}
#head h2 {
- margin: 0 0 0 100px;
- padding: 4px 0 0 42px;
- height: 18px;
- background-color: #EDE497;
- color: #726921;
- font-size: 13px;
- font-weight: normal;
- white-space: nowrap;
+ margin: 0 0 0 100px;
+ padding: 4px 0 0 42px;
+ height: 18px;
+ background-color: #EDE497;
+ color: #726921;
+ font-size: 13px;
+ font-weight: normal;
+ white-space: nowrap;
}
-#content1 {
- padding: 0 10px 10px 0;
- border-bottom: 1px solid #AF9D00;
+#content1 {
+ padding: 0 10px 10px 0;
+ border-bottom: 1px solid #AF9D00;
}
-#content2 {
- /* need non-zero top padding here to prevent margin propagation */
- padding: 10px 0 0 142px;
- max-width: 62em;
+#content2 {
+ /* need non-zero top padding here to prevent margin propagation */
+ padding: 10px 0 0 142px;
+ max-width: 62em;
}
-a {
- font-weight: bold;
- text-decoration: none;
+a {
+ font-weight: bold;
+ text-decoration: none;
}
-a:contains("http://") {
- font-weight: normal;
+a:contains("http://") {
+ font-weight: normal;
}
a.ext {
- font-style: italic;
+ font-style: italic;
}
-div.tabs {
- display: inline; /* IE double margin fix */
- float: left;
- clear: left;
- background-color: #FDF7C3;
- border: 1px solid #AF9D00;
- margin: 0 0 10px -132px;
- width: 120px;
- overflow: hidden;
+div.tabs {
+ display: inline; /* IE double margin fix */
+ float: left;
+ clear: left;
+ background-color: #FDF7C3;
+ border: 1px solid #AF9D00;
+ margin: 0 0 10px -132px;
+ width: 120px;
+ overflow: hidden;
}
-* html div.tabs {
- margin-bottom: 0; /* Grmpf .. IE6 is f**ing up ... */
+* html div.tabs {
+ margin-bottom: 0; /* Grmpf .. IE6 is f**ing up ... */
}
-div.tabs ul {
- margin: 0;
- padding: 0;
- list-style-type: none;
+div.tabs ul {
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
}
-div.tabs ul li {
- display: inline;
+div.tabs ul li {
+ display: inline;
}
-div.tabs ul li a {
- display: block;
- padding: 2px 5px;
- font-size: 13px;
- color: #726921;
- text-decoration: none;
- white-space: nowrap;
- font-weight: normal;
+div.tabs ul li a {
+ display: block;
+ padding: 2px 5px;
+ font-size: 13px;
+ color: #726921;
+ text-decoration: none;
+ white-space: nowrap;
+ font-weight: normal;
}
-div.tabs ul li a:visited, div.tabs ul li a:active {
- color: #726921;
- text-decoration: none;
+div.tabs ul li a:visited, div.tabs ul li a:active {
+ color: #726921;
+ text-decoration: none;
}
div.tabs li.current a {
- background-position: 100% -150px;
- border-width: 0px;
+ background-position: 100% -150px;
+ border-width: 0px;
}
div.tabs li.current span {
- background-position: 0% -150px;
- padding-bottom: 6px;
+ background-position: 0% -150px;
+ padding-bottom: 6px;
}
-div.tabs ul li a:hover, div.tabs ul li.current a {
- color: #726921;
- text-decoration: none;
- background-color: #EDE497;
+div.tabs ul li a:hover, div.tabs ul li.current a {
+ color: #726921;
+ text-decoration: none;
+ background-color: #EDE497;
}
-#footer {
- clear: both;
- padding: 4px 10px 4px 142px;
- color: #726921;
- white-space: nowrap;
- text-align: right;
- max-width: 62em;
+#footer {
+ clear: both;
+ padding: 4px 10px 4px 142px;
+ color: #726921;
+ white-space: nowrap;
+ text-align: right;
+ max-width: 62em;
}
-#footer span {
- font-size: 10px;
+#footer span {
+ font-size: 10px;
}
-#footer a, #footer a:active, #footer a:visited {
- color: #726921;
- text-decoration: none;
+#footer a, #footer a:active, #footer a:visited {
+ color: #726921;
+ text-decoration: none;
}
-#footer a:hover {
- background-color: inherit;
- text-decoration: underline;
+#footer a:hover {
+ background-color: inherit;
+ text-decoration: underline;
}
-dl.attention {
- border: 1px solid #AADD88;
- background-color: #EEFFDD;
- padding: 4px;
+dl.attention {
+ border: 1px solid #AADD88;
+ background-color: #EEFFDD;
+ padding: 4px;
}
-dl.warning {
- border: 1px solid #DDAA88;
- background-color: #FFEEDD;
- padding: 4px;
+dl.warning {
+ border: 1px solid #DDAA88;
+ background-color: #FFEEDD;
+ padding: 4px;
}
-dl.note {
- border: 1px solid A0C2C2;
- background-color: #F0F8F8;
- padding: 4px;
+dl.note {
+ border: 1px solid A0C2C2;
+ background-color: #F0F8F8;
+ padding: 4px;
}
-table.senf {
- width: 95%;
- margin: 0 auto;
- border: 1px solid #AAAAAA;
- padding: 2px;
- border-spacing: 0;
+table.senf {
+ width: 95%;
+ margin: 0 auto;
+ border: 1px solid #AAAAAA;
+ padding: 2px;
+ border-spacing: 0;
}
-table.senf td,th {
- border: 2px solid white;
- background-color: #EEEEEE;
- padding: 2px 4px;
- text-align: left;
+table.senf td,th {
+ border: 2px solid white;
+ background-color: #EEEEEE;
+ padding: 2px 4px;
+ text-align: left;
}
-table.senf th {
- background-color: #DDDDDD;
- text-align: center;
- font-weight: bold;
+table.senf th {
+ background-color: #DDDDDD;
+ text-align: center;
+ font-weight: bold;
}
-dl.bug, dl.fixme, dl.todo, dl.idea {
- border: 1px solid #EE0000;
- border-left-width: 4px;
- background-color: #FFDDDD;
- padding: 0 10px;
+dl.bug, dl.fixme, dl.todo, dl.idea {
+ border: 1px solid #EE0000;
+ border-left-width: 4px;
+ background-color: #FFDDDD;
+ padding: 0 10px;
}
-dl.xref-bug, dl.xref-fix, dl.xref-todo, dl.xref-idea {
- border: 1px solid #CC8888;
- padding: 2px 3px;
- margin: 4px 8px 4px 2px;
- background-color: #FFEEEE;
- color: #666666;
- font-size: 9px;
- overflow: hidden;
+dl.xref-bug, dl.xref-fix, dl.xref-todo, dl.xref-idea {
+ border: 1px solid #CC8888;
+ padding: 2px 3px;
+ margin: 4px 8px 4px 2px;
+ background-color: #FFEEEE;
+ color: #666666;
+ font-size: 9px;
+ overflow: hidden;
}
dl.xref-bug dt, dl.xref-fix dt, dl.xref-todo dt, dl.xref-idea dt,
-dl.xref-bug dd, dl.xref-fix dd, dl.xref-todo dd, dl.xref-idea dd {
- display: inline;
- margin: 0;
- padding: 0;
+dl.xref-bug dd, dl.xref-fix dd, dl.xref-todo dd, dl.xref-idea dd {
+ display: inline;
+ margin: 0;
+ padding: 0;
}
-dl.xref-bug a, dl.xref-fix a, dl.xref-todo a, dl.xref-idea a {
- color: #6666FF;
+dl.xref-bug a, dl.xref-fix a, dl.xref-todo a, dl.xref-idea a {
+ color: #6666FF;
}
-dl.fixme {
- border-color: #EEEE00;
- background-color: #FFFFDD;
+dl.fixme {
+ border-color: #EEEE00;
+ background-color: #FFFFDD;
}
-dl.xref-fix {
- border-color: #CCCC88;
- background-color: #FFFFEE;
+dl.xref-fix {
+ border-color: #CCCC88;
+ background-color: #FFFFEE;
}
-dl.todo {
- border-color: #00AA00;
- background-color: #DDFFDD;
+dl.todo {
+ border-color: #00AA00;
+ background-color: #DDFFDD;
}
-dl.xref-todo {
- border-color: #88CC88;
- background-color: #EEFFEE;
+dl.xref-todo {
+ border-color: #88CC88;
+ background-color: #EEFFEE;
}
-dl.idea {
- border-color: #AAAAAA;
- background-color: #EEEEEE;
+dl.idea {
+ border-color: #AAAAAA;
+ background-color: #EEEEEE;
}
-dl.xref-idea {
- border-color: #CCCCCC;
- background-color: #F8F8F8;
+dl.xref-idea {
+ border-color: #CCCCCC;
+ background-color: #F8F8F8;
}
table {
- width: 100%;
+ width: 100%;
}
-div.ah {
- margin-right: 10px;
+div.ah {
+ margin-right: 10px;
}
-div.nav {
- width: auto;
- background-color: white;
- border: none;
- border-bottom: 1px solid #AF9D00;
- padding: 5px 0;
- margin: 0;
+div.nav {
+ width: auto;
+ background-color: white;
+ border: none;
+ border-bottom: 1px solid #AF9D00;
+ padding: 5px 0;
+ margin: 0;
}
div.qindex {
- width: auto;
- background-color: #e8eef2;
- border: 1px solid #84b0c7;
- text-align: center;
- margin: 2px 0;
- padding: 2px;
- line-height: 140%;
+ width: auto;
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px 0;
+ padding: 2px;
+ line-height: 140%;
}
-dl.parameters dd table {
- width: auto;
+dl.parameters dd table {
+ width: auto;
}
-table.glossary {
- border: none;
- border-spacing: 0;
+table.glossary {
+ border: none;
+ border-spacing: 0;
}
-table.glossary tr td {
- border: none;
- border-bottom: 4px solid white;
- vertical-align: top;
- padding: 2px 4px;
- background-color: #F0F0F0;
+table.glossary tr td {
+ border: none;
+ border-bottom: 4px solid white;
+ vertical-align: top;
+ padding: 2px 4px;
+ background-color: #F0F0F0;
}
table.glossary tr td:first-child {
- font-weight: bold;
- white-space: nowrap;
- padding-right: 10px;
+ font-weight: bold;
+ white-space: nowrap;
+ padding-right: 10px;
}
-table.members td:first-child {
- width: 35%;
+table.members td:first-child {
+ width: 35%;
}
\ No newline at end of file
;; Configuration file for cc-ide.el (Emacs C++ IDE extension, see http://g0dil.de)
+ (defconst senf-c-style
+ '((c-basic-offset . 4)
+ (c-cleanup-list . (empty-defun-braces
+ defun-close-semi
+ list-close-comma
+ scope-operator
+ compact-empty-funcall))
+ (c-hanging-braces-alist . ((namespace-open after)
+ (namespace-close before after)
+ (brace-list-open)
+ (brace-entry-open)
+ (substatement-open after)
+ (block-close . c-snug-do-while)
+ (extern-lang-open after)
+ (inexpr-class-open after)
+ (inexpr-class-close before)))
+ (c-offsets-alist . ((namespace-open . 0)
+ (namespace-close . -)
+ (innamespace . +)
+ (statement-block-intro . +)
+ (substatement-open . 0)
+ (label . 0)
+ (statement-cont . +))) ))
+
+(c-add-style "senf" senf-c-style)
+
(set (make-local-variable 'ccide-file-vars)
'(( fill-column . 100 )
( c-file-style . "senf" )
+ ( indent-tabs-mode . nil )
( ispell-local-dictionary . "american" )))
(set (make-local-variable 'ccide-default-copyright)
(concat "//\n"
- "// This program is free software; you can redistribute it and/or modify\n"
- "// it under the terms of the GNU General Public License as published by\n"
- "// the Free Software Foundation; either version 2 of the License, or\n"
- "// (at your option) any later version.\n"
- "//\n"
- "// This program is distributed in the hope that it will be useful,\n"
- "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
- "// GNU General Public License for more details.\n"
- "//\n"
- "// You should have received a copy of the GNU General Public License\n"
- "// along with this program; if not, write to the\n"
- "// Free Software Foundation, Inc.,\n"
- "// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"))
+ "// This program is free software; you can redistribute it and/or modify\n"
+ "// it under the terms of the GNU General Public License as published by\n"
+ "// the Free Software Foundation; either version 2 of the License, or\n"
+ "// (at your option) any later version.\n"
+ "//\n"
+ "// This program is distributed in the hope that it will be useful,\n"
+ "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "// GNU General Public License for more details.\n"
+ "//\n"
+ "// You should have received a copy of the GNU General Public License\n"
+ "// along with this program; if not, write to the\n"
+ "// Free Software Foundation, Inc.,\n"
+ "// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"))
(let ((local-conf (expand-file-name "project-local.el" ccide-project-root)))
(if (file-readable-p local-conf)
$mode=0;
while (<STDIN>) {
if ($mode==0) {
- if (/^$/) {
+ if (/^$/) {
$mode=1;
} else {
print;
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
-STRIP_FROM_PATH =
-STRIP_FROM_INC_PATH =
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DISTRIBUTE_GROUP_DOC = NO
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
-ALIASES =
+ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
SUBGROUPING = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
-ENABLED_SECTIONS =
+ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
-FILE_VERSION_FILTER =
+FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
-WARN_LOGFILE =
+WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
*.ct \
*.cti \
*.ih \
- *.mpp
+ *.mpp
RECURSIVE = NO
EXCLUDE = doc
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = *.test.cc
-EXAMPLE_PATH =
+EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
-IMAGE_PATH =
-INPUT_FILTER =
-FILTER_PATTERNS =
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
-IGNORE_PREFIX =
+IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
-HTML_HEADER =
-HTML_FOOTER =
-HTML_STYLESHEET =
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
-CHM_FILE =
-HHC_LOCATION =
+CHM_FILE =
+HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
-EXTRA_PACKAGES =
-LATEX_HEADER =
+EXTRA_PACKAGES =
+LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
-RTF_STYLESHEET_FILE =
-RTF_EXTENSIONS_FILE =
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
-XML_SCHEMA =
-XML_DTD =
+XML_SCHEMA =
+XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
-PERLMOD_MAKEVAR_PREFIX =
+PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
+# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH = libs
-INCLUDE_FILE_PATTERNS =
+INCLUDE_FILE_PATTERNS =
PREDEFINED = DOXYGEN
EXPAND_AS_DEFINED = DefineCommand
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
-# Configuration::additions related to external references
+# Configuration::additions related to external references
#---------------------------------------------------------------------------
-TAGFILES =
-GENERATE_TAGFILE =
+TAGFILES =
+GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
+# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = NO
GRAPHICAL_HIERARCHY = NO
DIRECTORY_GRAPH = NO
DOT_IMAGE_FORMAT = png
-DOT_PATH =
-DOTFILE_DIRS =
+DOT_PATH =
+DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 800
MAX_DOT_GRAPH_HEIGHT = 1200
MAX_DOT_GRAPH_DEPTH = 1000
GENERATE_LEGEND = YES
DOT_CLEANUP = NO
#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
+# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
dep_add_keys = (
'@INCLUDE', 'HTML_HEADER', 'HTML_FOOTER', 'TAGFILES', 'INPUT_FILTER'
)
-
+
default_file_patterns = (
'*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx',
'*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++',
for f in files:
filename = os.path.normpath(os.path.join(root, f))
if ( reduce(lambda x, y: x or fnmatch(f, y),
- file_patterns, False)
+ file_patterns, False)
and not reduce(lambda x, y: x or fnmatch(f, y),
exclude_patterns, False) ):
sources.append(filename)
# If for any referenced tagfile no url can be found, 'installdox'
# will *not* be called and a warning about the missing url is
# generated.
-
+
if data.get('GENERATE_HTML','YES').upper() == "YES":
output_dir = os.path.normpath(os.path.join( source[0].dir.abspath,
data.get("OUTPUT_DIRECTORY","."),
args.append("-l %s@%s" % ( os.path.basename(tagfile), url ))
if args:
actions.append(env.Action('cd %s && ./installdox %s' % (output_dir, " ".join(args))))
-
+
actions.append(env.Action([ "touch $TARGETS" ]))
return actions
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
framework however semi-automatically creates the necessary cross-reference information to
cross-link the different module documentations. The unit-tests as well are run on a per-module
basis.
-
+
\section Standard Build Configuration
When the \c SConsctruct and \c SConscript files are build using the default SENFSCons helpers,
by default all libraries and binaries are built. Some additional targets are
<dl><dt><tt>scons all_tests</tt></dt><dd>Build all unit tests</dd>
-
+
<dt><tt>scons all_docs</tt></dt><dd>Build documentation of all modules</dd>
-
+
<dt><tt>scons all</tt></dt><dd>Build all targets including binaries, libraries, documentation,
tests andpossible further targets </dd>
directory.
\see
- \ref sconstruct \n
- \ref sconscript \n
+ \ref sconstruct \n
+ \ref sconscript \n
\ref sconfig \n
\ref builder
*/
The general structure of the \c SConstruct file is
\li make the \c senfscons directory accessible
\li tell the SENFScons infrastructure, which frameworks you intend to use and let SENFScons
- built a construction environment for you
+ built a construction environment for you
\li configure the construction environment
\li load module sconscript file
\li specify global build targets
The first part, <i>making the \c senfscons directory accessible</i> will always stay the
same. See the template file for how this is done.
-
+
<i>Simplifying the use of more complex frameworks</i> is one of the most important things why
SENFScons exists. If you only use very simple libraries, the configuration is quite
simple. However for more complex frameworks the configuration can get quite complicated. This is
software. Just remember, you can use all of python and all of SCons here. SENFScons just
provides some additional helpers to make things simpler and more concise.
- \see
- \ref use \n
- \ref target
+ \see
+ \ref use \n
+ \ref target
*/
/** \page sconscript The Module 'SConscript' Files
targets of every module.
\see
- \ref target
+ \ref target
*/
/** \page sconfig The 'SConfig' File
-
+
To configure the build environment to the local environment, a \c SConfig file may be created in
the projects root directory. The supported parameters are
-
+
<dl><dt>\c CXX</dt><dd>C++ compiler to use</dd>
<dt>\c EXTRA_DEFINES</dt><dd>preprocessor symbols to be defined locally</dd>
<dt>\c EXTRA_LIBS</dt><dd>additional libraries needed for a local build</dd></dl>
// mode: c++
// fill-column: 100
// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// mode: flyspell
// mode: auto-fill
-// ispell-local-dictionary: "american"
// End:
# \brief Build helpers and utilities
#
# The SENFSCons package contains a number of build helpers and
-# utilities which are used to simplify commmon tasks.
+# utilities which are used to simplify commmon tasks.
#
# The utitlities of this package are grouped into:
# <dl><dt>\ref use</dt><dd>help using complex environments and
## \defgroup use Predefined Framework Configurators
#
# The following framework configurators are used in the top level \c
-# SConstruct file to simplify more complex configurations.
+# SConstruct file to simplify more complex configurations.
#
# Each of the framework configurators introduces additional
# configuration parameters to \ref sconfig
testSources = glob.glob("*.test.cc")
sources = [ x for x in glob.glob("*.cc") if x not in testSources and x not in exclude ]
return (sources, testSources)
-
+
## \brief Add generic standard targets for every module
#
# This target helper should be called in the top-level \c SConstruct file
# targets. Right now, these are
# \li clean up \c .sconsign, \c .sconf_temp and \c config.log on
# <tt>scons -c all</tt>
-#
+#
# \ingroup target
def StandardTargets(env):
env.Clean(env.Alias('all'), [ '.sconsign', '.sconf_temp', 'config.log' ])
xref = os.path.join(xmlnode.dir.abspath,type+".xml")
xref_pp = env.Command(xref+'i', [ xref, os.path.join(basedir,'xrefxtract.xslt'), xmlnode ],
[ "test -s $SOURCE && xsltproc -o $TARGET" +
- " --stringparam module $MODULE" +
+ " --stringparam module $MODULE" +
" --stringparam type $TYPE" +
" ${SOURCES[1]} $SOURCE || touch $TARGET" ],
MODULE = xmlnode.dir.dir.dir.name,
commands.append(
"sed -e 's/\\$$title/$TITLE/g' -e 's/\\$$projectname/Overview/g' ${SOURCES[%d]} >> $TARGET"
% (HTML_HEADER and 3 or 2))
-
+
xref = env.Command("doc/html/xref.html", sources, commands,
TITLE = TITLE)