git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@129 270642c3-0616-0410...
g0dil [Tue, 10 Oct 2006 09:34:29 +0000 (09:34 +0000)]
187 files changed:
Packets/.cvsignore [new file with mode: 0644]
Packets/DataPacket.cc [new file with mode: 0644]
Packets/DataPacket.cti [new file with mode: 0644]
Packets/DataPacket.hh [new file with mode: 0644]
Packets/Doxyfile [new file with mode: 0644]
Packets/EthernetPacket.cc [new file with mode: 0644]
Packets/EthernetPacket.cti [new file with mode: 0644]
Packets/EthernetPacket.hh [new file with mode: 0644]
Packets/EthernetPacket.test.cc [new file with mode: 0644]
Packets/FUTURE [new file with mode: 0644]
Packets/GenericPacket.ct [new file with mode: 0644]
Packets/GenericPacket.cti [new file with mode: 0644]
Packets/GenericPacket.hh [new file with mode: 0644]
Packets/IpV4Packet.cc [new file with mode: 0644]
Packets/IpV4Packet.cti [new file with mode: 0644]
Packets/IpV4Packet.hh [new file with mode: 0644]
Packets/IpV4Packet.test.cc [new file with mode: 0644]
Packets/Packet.cc [new file with mode: 0644]
Packets/Packet.cci [new file with mode: 0644]
Packets/Packet.ct [new file with mode: 0644]
Packets/Packet.cti [new file with mode: 0644]
Packets/Packet.hh [new file with mode: 0644]
Packets/Packet.ih [new file with mode: 0644]
Packets/Packet.mpp [new file with mode: 0644]
Packets/Packet.test.cc [new file with mode: 0644]
Packets/PacketRegistry.cc [new file with mode: 0644]
Packets/PacketRegistry.ct [new file with mode: 0644]
Packets/PacketRegistry.cti [new file with mode: 0644]
Packets/PacketRegistry.hh [new file with mode: 0644]
Packets/PacketRegistry.ih [new file with mode: 0644]
Packets/PacketRegistry.test.cc [new file with mode: 0644]
Packets/ParseArray.cti [new file with mode: 0644]
Packets/ParseArray.hh [new file with mode: 0644]
Packets/ParseArray.ih [new file with mode: 0644]
Packets/ParseArray.test.cc [new file with mode: 0644]
Packets/ParseInt.hh [new file with mode: 0644]
Packets/ParseInt.ih [new file with mode: 0644]
Packets/ParseInt.test.cc [new file with mode: 0644]
Packets/ParseListS.ct [new file with mode: 0644]
Packets/ParseListS.cti [new file with mode: 0644]
Packets/ParseListS.hh [new file with mode: 0644]
Packets/ParseListS.ih [new file with mode: 0644]
Packets/ParseListS.test.cc [new file with mode: 0644]
Packets/ParseVec.ct [new file with mode: 0644]
Packets/ParseVec.cti [new file with mode: 0644]
Packets/ParseVec.hh [new file with mode: 0644]
Packets/ParseVec.test.cc [new file with mode: 0644]
Packets/ParserBase.cti [new file with mode: 0644]
Packets/ParserBase.hh [new file with mode: 0644]
Packets/ParserBase.ih [new file with mode: 0644]
Packets/ParserBase.test.cc [new file with mode: 0644]
Packets/RTCPPacket.cc [new file with mode: 0644]
Packets/RTCPPacket.cti [new file with mode: 0644]
Packets/RTCPPacket.hh [new file with mode: 0644]
Packets/RTCPPacket.test.cc [new file with mode: 0644]
Packets/RTPPacket.cc [new file with mode: 0644]
Packets/RTPPacket.cti [new file with mode: 0644]
Packets/RTPPacket.hh [new file with mode: 0644]
Packets/RTPPacket.test.cc [new file with mode: 0644]
Packets/SConscript [new file with mode: 0644]
Packets/TODO [new file with mode: 0644]
Packets/UDPPacket.cc [new file with mode: 0644]
Packets/UDPPacket.cti [new file with mode: 0644]
Packets/UDPPacket.hh [new file with mode: 0644]
Packets/UDPPacket.test.cc [new file with mode: 0644]
Packets/docstub.hh [new file with mode: 0644]
Packets/imgconvert.mak [new file with mode: 0644]
Packets/main.test.cc [new file with mode: 0644]
Packets/satcom.css [new file with mode: 0644]
Packets/structure.dia [new file with mode: 0644]
Packets/typeidvalue.cci [new file with mode: 0644]
Packets/typeidvalue.cti [new file with mode: 0644]
Packets/typeidvalue.hh [new file with mode: 0644]
SConfig [new file with mode: 0644]
SConstruct [new file with mode: 0644]
Scheduler/SConscript [new file with mode: 0644]
Scheduler/Scheduler.cc [new file with mode: 0644]
Scheduler/Scheduler.cci [new file with mode: 0644]
Scheduler/Scheduler.ct [new file with mode: 0644]
Scheduler/Scheduler.cti [new file with mode: 0644]
Scheduler/Scheduler.hh [new file with mode: 0644]
Scheduler/Scheduler.test.cc [new file with mode: 0644]
Scheduler/main.test.cc [new file with mode: 0644]
Socket/AddressingPolicy.hh [new file with mode: 0644]
Socket/BSDSocketProtocol.cc [new file with mode: 0644]
Socket/BSDSocketProtocol.hh [new file with mode: 0644]
Socket/BufferingPolicy.cc [new file with mode: 0644]
Socket/BufferingPolicy.hh [new file with mode: 0644]
Socket/ClientSocketHandle.ct [new file with mode: 0644]
Socket/ClientSocketHandle.cti [new file with mode: 0644]
Socket/ClientSocketHandle.hh [new file with mode: 0644]
Socket/ClientSocketHandle.test.cc [new file with mode: 0644]
Socket/CommunicationPolicy.cc [new file with mode: 0644]
Socket/CommunicationPolicy.cti [new file with mode: 0644]
Socket/CommunicationPolicy.hh [new file with mode: 0644]
Socket/Doxyfile [new file with mode: 0644]
Socket/FileHandle.cc [new file with mode: 0644]
Socket/FileHandle.cci [new file with mode: 0644]
Socket/FileHandle.hh [new file with mode: 0644]
Socket/FileHandle.ih [new file with mode: 0644]
Socket/FileHandle.test.cc [new file with mode: 0644]
Socket/FramingPolicy.hh [new file with mode: 0644]
Socket/GenericAddressingPolicy.cc [new file with mode: 0644]
Socket/GenericAddressingPolicy.cti [new file with mode: 0644]
Socket/GenericAddressingPolicy.hh [new file with mode: 0644]
Socket/INetAddressing.cc [new file with mode: 0644]
Socket/INetAddressing.cci [new file with mode: 0644]
Socket/INetAddressing.hh [new file with mode: 0644]
Socket/INetAddressing.test.cc [new file with mode: 0644]
Socket/INetProtocol.cc [new file with mode: 0644]
Socket/INetProtocol.hh [new file with mode: 0644]
Socket/LLAddressing.cc [new file with mode: 0644]
Socket/LLAddressing.cci [new file with mode: 0644]
Socket/LLAddressing.ct [new file with mode: 0644]
Socket/LLAddressing.cti [new file with mode: 0644]
Socket/LLAddressing.hh [new file with mode: 0644]
Socket/LLAddressing.ih [new file with mode: 0644]
Socket/LLAddressing.test.cc [new file with mode: 0644]
Socket/PacketSocketHandle.cc [new file with mode: 0644]
Socket/PacketSocketHandle.ct [new file with mode: 0644]
Socket/PacketSocketHandle.cti [new file with mode: 0644]
Socket/PacketSocketHandle.hh [new file with mode: 0644]
Socket/PacketSocketHandle.ih [new file with mode: 0644]
Socket/PacketSocketHandle.test.cc [new file with mode: 0644]
Socket/ProtocolClientSocketHandle.cti [new file with mode: 0644]
Socket/ProtocolClientSocketHandle.hh [new file with mode: 0644]
Socket/ProtocolClientSocketHandle.mpp [new file with mode: 0644]
Socket/ProtocolClientSocketHandle.test.cc [new file with mode: 0644]
Socket/ProtocolServerSocketHandle.cti [new file with mode: 0644]
Socket/ProtocolServerSocketHandle.hh [new file with mode: 0644]
Socket/ProtocolServerSocketHandle.mpp [new file with mode: 0644]
Socket/ProtocolServerSocketHandle.test.cc [new file with mode: 0644]
Socket/ReadWritePolicy.cc [new file with mode: 0644]
Socket/ReadWritePolicy.cti [new file with mode: 0644]
Socket/ReadWritePolicy.hh [new file with mode: 0644]
Socket/SConscript [new file with mode: 0644]
Socket/ServerSocketHandle.cti [new file with mode: 0644]
Socket/ServerSocketHandle.hh [new file with mode: 0644]
Socket/ServerSocketHandle.test.cc [new file with mode: 0644]
Socket/SocketHandle.cc [new file with mode: 0644]
Socket/SocketHandle.cci [new file with mode: 0644]
Socket/SocketHandle.ct [new file with mode: 0644]
Socket/SocketHandle.cti [new file with mode: 0644]
Socket/SocketHandle.hh [new file with mode: 0644]
Socket/SocketHandle.ih [new file with mode: 0644]
Socket/SocketHandle.test.cc [new file with mode: 0644]
Socket/SocketPolicy.ct [new file with mode: 0644]
Socket/SocketPolicy.hh [new file with mode: 0644]
Socket/SocketPolicy.ih [new file with mode: 0644]
Socket/SocketPolicy.test.cc [new file with mode: 0644]
Socket/SocketPolicy.test.hh [new file with mode: 0644]
Socket/SocketProtocol.cc [new file with mode: 0644]
Socket/SocketProtocol.cci [new file with mode: 0644]
Socket/SocketProtocol.cti [new file with mode: 0644]
Socket/SocketProtocol.hh [new file with mode: 0644]
Socket/SocketProtocol.test.cc [new file with mode: 0644]
Socket/SocketProtocol.test.hh [new file with mode: 0644]
Socket/TCPProtocol.cc [new file with mode: 0644]
Socket/TCPProtocol.hh [new file with mode: 0644]
Socket/TCPSocketHandle.cc [new file with mode: 0644]
Socket/TCPSocketHandle.hh [new file with mode: 0644]
Socket/TCPSocketHandle.test.cc [new file with mode: 0644]
Socket/main.test.cc [new file with mode: 0644]
Utils/Exception.cc [new file with mode: 0644]
Utils/Exception.hh [new file with mode: 0644]
Utils/SConscript [new file with mode: 0644]
Utils/TypeInfo.cc [new file with mode: 0644]
Utils/TypeInfo.hh [new file with mode: 0644]
Utils/TypeInfo.test.cc [new file with mode: 0644]
Utils/impl/demangle.h [new file with mode: 0644]
Utils/impl/membind.hh [new file with mode: 0644]
Utils/intrusive_refcount.cci [new file with mode: 0644]
Utils/intrusive_refcount.hh [new file with mode: 0644]
Utils/intrusive_refcount.test.cc [new file with mode: 0644]
Utils/main.test.cc [new file with mode: 0644]
Utils/membind.hh [new file with mode: 0644]
Utils/membind.test.cc [new file with mode: 0644]
satscons/BoostUnitTests.py [new file with mode: 0644]
satscons/Doxyfile.template [new file with mode: 0644]
satscons/Doxygen.py [new file with mode: 0644]
satscons/SConscript.template [new file with mode: 0644]
satscons/SConstruct.template [new file with mode: 0644]
satscons/SatSCons.py [new file with mode: 0644]
satscons/__init__.py [new file with mode: 0644]
satscons/nodeglob.py [new file with mode: 0644]
satscons/pdflatex.py [new file with mode: 0644]
satscons/satconf.py [new file with mode: 0644]

diff --git a/Packets/.cvsignore b/Packets/.cvsignore
new file mode 100644 (file)
index 0000000..9064a29
--- /dev/null
@@ -0,0 +1,10 @@
+SConfig
+.doc.stamp
+.test.stamp
+.sconf_temp
+.sconsign
+config.log
+doc
+test
+structure.png
+.clean
diff --git a/Packets/DataPacket.cc b/Packets/DataPacket.cc
new file mode 100644 (file)
index 0000000..91e80cf
--- /dev/null
@@ -0,0 +1,54 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "DataPacket.hh"
+//#include "DataPacket.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void satcom::pkf::DataPacket::v_nextInterpreter()
+    const
+{}
+
+prefix_ void satcom::pkf::DataPacket::v_finalize()
+{}
+
+prefix_ void satcom::pkf::DataPacket::v_dump(std::ostream & os)
+    const
+{
+    os << "Payload:\n"
+       << "  size          : " << size() << "\n";
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/DataPacket.cti b/Packets/DataPacket.cti
new file mode 100644 (file)
index 0000000..f16bbb3
--- /dev/null
@@ -0,0 +1,44 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "DataPacket.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Arg>
+prefix_ satcom::pkf::DataPacket::DataPacket(Arg const & arg)
+    : Packet(arg) 
+{}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/DataPacket.hh b/Packets/DataPacket.hh
new file mode 100644 (file)
index 0000000..480f3cd
--- /dev/null
@@ -0,0 +1,79 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_DataPacket_
+#define HH_DataPacket_ 1
+
+// Custom includes
+#include "Packet.hh"
+
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+
+    /** \brief Non-interpreted Packet
+
+        A DataPacket is an uninterpreted blob of data. It is terminal
+        in the sense, that no further packet header may follow after
+        this packet. A DataPacket implements the abstract Packet
+        interface and nothing more.
+     */
+    class DataPacket : public Packet
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<DataPacket>::ptr ptr;
+        typedef iterator byte_iterator;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        static void init() {}
+        static bool check(iterator const & b, iterator const & e) { return true; }
+
+    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;
+
+        friend class Packet;
+    };
+
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "DataPacket.cci"
+//#include "DataPacket.ct"
+#include "DataPacket.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Doxyfile b/Packets/Doxyfile
new file mode 100644 (file)
index 0000000..5701f22
--- /dev/null
@@ -0,0 +1,273 @@
+# Doxyfile 1.4.2
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = "SatCom PacketFramework: Packet library"
+PROJECT_NUMBER         = "Version 0.0.1"
+OUTPUT_DIRECTORY       = doc
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = NO
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = /share/izo/home/stefan/group/FhG/Seminar/example/
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = YES
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = YES
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = NO
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = .
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.C \
+                         *.CC \
+                         *.C++ \
+                         *.II \
+                         *.I++ \
+                         *.H \
+                         *.HH \
+                         *.H++ \
+                         *.CS \
+                         *.PHP \
+                         *.PHP3 \
+                         *.M \
+                         *.MM \
+                         *.cci \
+                         *.ct \
+                         *.cti \
+                         *.ih
+RECURSIVE              = NO
+EXCLUDE                = doc
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = *.test.cc
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 5
+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        = satcom.css
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# 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  = 
+PREDEFINED             = DOXYGEN
+EXPAND_AS_DEFINED      = DefineCommand
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = NO
+HAVE_DOT               = YES
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = NO
+DIRECTORY_GRAPH        = NO
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 800
+MAX_DOT_GRAPH_HEIGHT   = 1200
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = YES
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = NO
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/Packets/EthernetPacket.cc b/Packets/EthernetPacket.cc
new file mode 100644 (file)
index 0000000..f0e468e
--- /dev/null
@@ -0,0 +1,114 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "EthernetPacket.hh"
+//#include "EthernetPacket.ih"
+
+// Custom includes
+#include <iomanip>
+#include <boost/format.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    namespace pkf = satcom::pkf;
+    pkf::PacketRegistry<pkf::EtherTypes>::RegistrationProxy<pkf::EthVLanPacket> 
+        registerEthVLanPacket(0x8100);
+}
+
+prefix_ void satcom::pkf::EthernetPacket::v_nextInterpreter()
+    const
+{
+    // TODO: Add LLC/SNAP support -> only use the registry
+    // for type() values >=1536, otherwise expect an LLC header
+    registerInterpreter(type(),begin()+bytes(),end());
+}
+
+namespace {
+    
+    void dumpmac(std::ostream & os, satcom::pkf::EthernetPacket::Parse_MAC mac)
+    {
+        for (unsigned i = 0; i < 6; ++i) {
+            if (i > 0) 
+                os << ':';
+            os << std::hex << std::setw(2) << std::setfill('0')
+               << unsigned(mac[i]);
+        }
+    }
+
+}
+
+prefix_ void satcom::pkf::EthernetPacket::v_dump(std::ostream & os)
+    const
+{
+    if (type() <= 1500)
+        os << "Ethernet 802.3";
+    else if (type() >= 0x600)
+        os << "Ethernet II (DIX)";
+    else 
+        os << "Ethernet 802.3 (bad ethertype >1500 and <1536)";
+    os << ": \n"
+       << "  destination   : ";
+    dumpmac(os,destination());
+    os << "\n"
+       << "  source        : ";
+    dumpmac(os,source());
+    os << "\n"
+       << "  ethertype     : " << std::hex << std::setw(4) << std::setfill('0')
+       << unsigned(type()) << "\n" << std::dec;
+}
+
+prefix_ void satcom::pkf::EthernetPacket::v_finalize()
+{}
+
+prefix_ void satcom::pkf::EthVLanPacket::v_nextInterpreter()
+    const
+{
+    // TODO: Add LLC/SNAP support -> only use the registry
+    // for type() values >=1536, otherwise expect an LLC header
+    registerInterpreter(type(),begin()+bytes(),end());
+}
+
+prefix_ void satcom::pkf::EthVLanPacket::v_finalize()
+{}
+
+prefix_ void satcom::pkf::EthVLanPacket::v_dump(std::ostream & os)
+    const
+{
+    os << "Ethernet 802.1q (VLAN):\n"
+       << "  priority      : " << priority() << "\n"
+       << "  cfi           : " << cfi() << "\n"
+       << "  vlan-ID       : " << vlanId() << "\n"
+       << "  ethertype     : " << boost::format("%04x") % type() << "\n";
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/EthernetPacket.cti b/Packets/EthernetPacket.cti
new file mode 100644 (file)
index 0000000..132e2de
--- /dev/null
@@ -0,0 +1,49 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "EthernetPacket.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Arg>
+prefix_ satcom::pkf::EthernetPacket::EthernetPacket(Arg const & arg)
+    : Packet(arg)
+{}
+
+template <class Arg>
+prefix_ satcom::pkf::EthVLanPacket::EthVLanPacket(Arg const & arg)
+    : Packet(arg)
+{}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/EthernetPacket.hh b/Packets/EthernetPacket.hh
new file mode 100644 (file)
index 0000000..ae4fdb2
--- /dev/null
@@ -0,0 +1,152 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_EthernetPacket_
+#define HH_EthernetPacket_ 1
+
+// Custom includes
+#include "Packet.hh"
+#include "ParseInt.hh"
+#include "ParseArray.hh"
+#include "PacketRegistry.hh"
+
+//#include "EthernetPacket.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+    
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_Ethernet : public ParserBase<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_Ethernet<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        Parse_Ethernet() {}
+        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 {
+        typedef boost::uint16_t key_t;
+    };
+
+    class EthernetPacket
+        : public Packet, 
+          public Parse_Ethernet<Packet::iterator, EthernetPacket>, 
+          public PacketRegistryMixin<EtherTypes,EthernetPacket>
+    {
+        using PacketRegistryMixin<EtherTypes,EthernetPacket>::registerInterpreter;
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<EthernetPacket>::ptr ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    private:
+        template <class Arg>
+        EthernetPacket(Arg const & arg);
+
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+        virtual void v_dump(std::ostream & os) const;
+
+        friend class Packet;
+    };
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_EthVLan : public ParserBase<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_Ethernet<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        Parse_EthVLan() {}
+        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;
+        typedef Parse_UInt16           < Iterator > Parse_Type;
+
+        Parse_Priority priority() const { return Parse_Priority(this->i()); }
+        Parse_CFI      cfi()      const { return Parse_CFI(this->i()); }
+        Parse_VLanId   vlanId()   const { return Parse_VLanId(this->i()); }
+        Parse_Type     type()     const { return Parse_Type(this->i()+2); }
+    };
+
+    class EthVLanPacket
+        : public Packet,
+          public Parse_EthVLan<Packet::iterator, EthVLanPacket>,
+          public PacketRegistryMixin<EtherTypes, EthVLanPacket>
+    {
+        using PacketRegistryMixin<EtherTypes, EthVLanPacket>::registerInterpreter;
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<EthVLanPacket>::ptr ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    private:
+        template <class Arg>
+        EthVLanPacket(Arg const & arg);
+
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+        virtual void v_dump(std::ostream & os) const;
+
+        friend class Packet;
+    };
+
+}}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "EthernetPacket.cci"
+//#include "EthernetPacket.ct"
+#include "EthernetPacket.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/EthernetPacket.test.cc b/Packets/EthernetPacket.test.cc
new file mode 100644 (file)
index 0000000..72e16d5
--- /dev/null
@@ -0,0 +1,95 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "EthernetPacket.test.hh"
+//#include "EthernetPacket.test.ih"
+
+// Custom includes
+#include "EthernetPacket.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+BOOST_AUTO_UNIT_TEST(ethernetPacket_parser)
+{
+    unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // destination MAC
+                             0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,  // source MAC
+                             0x10, 0x11 };                        // EtherType
+    typedef unsigned char * iterator;
+    Parse_Ethernet<iterator> p(data);
+
+    BOOST_CHECK_EQUAL( p.destination()[2], 0x03 );
+    BOOST_CHECK_EQUAL( p.source()[3], 0x0A );
+    BOOST_CHECK_EQUAL( p.type(), 0x1011 );
+}
+
+BOOST_AUTO_UNIT_TEST(ethernetPacket_packet)
+{
+    unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // destination MAC
+                             0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,  // source MAC
+                             0x10, 0x11 };                        // EtherType
+    EthernetPacket::ptr p (Packet::create<EthernetPacket>(data, data+sizeof(data)));
+
+    BOOST_CHECK_EQUAL( p->destination()[3], 0x04 );
+    BOOST_CHECK_EQUAL( p->source()[0], 0x07 );
+    BOOST_CHECK_EQUAL( p->type(), 0x1011 );
+
+    BOOST_CHECK_THROW( Packet::create<EthernetPacket>(data, data+sizeof(data)-1), 
+                       TruncatedPacketException );
+}
+
+BOOST_AUTO_UNIT_TEST(ethernetPacket_chain)
+{
+    unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // destination MAC
+                             0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,  // source MAC
+                             0x81, 0x00,                          // EtherType: VLan
+                             0x92, 0x34,                          // VLAN prio, cfi, id
+                             0xab, 0xcd,                          // EtherType
+                             0xf0, 0xf1, 0xf2, 0xf3, 0xf4 };      // Payload
+
+    EthernetPacket::ptr p (Packet::create<EthernetPacket>(data, data+sizeof(data)));
+
+    BOOST_CHECK( p->next()->is<EthVLanPacket>() );
+    EthVLanPacket::ptr v (p->next()->as<EthVLanPacket>());
+    BOOST_CHECK_EQUAL( v->priority(), 4u );
+    BOOST_CHECK( v->cfi() );
+    BOOST_CHECK_EQUAL( v->vlanId(), 0x234u );
+    BOOST_CHECK_EQUAL( v->type(), 0xabcd );
+    BOOST_CHECK( v->next()->is<DataPacket>() );
+    BOOST_CHECK_EQUAL( *v->next()->begin(), 0xf0 );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/FUTURE b/Packets/FUTURE
new file mode 100644 (file)
index 0000000..36f879a
--- /dev/null
@@ -0,0 +1,71 @@
+Optimize the PacketRegistry using a vtable like approach. This vtable
+approach should be implemented as a generic vtable library:
+
+Every class which shall be extensible needs to inheriv from the vtable
+base class. This base class adds an integer member to the class. This
+baseclass uses the CRTP pattern to initialize this integer to a type
+specific value.
+
+To get theese values, we use a typeid registry. The typeid-registry is
+a tempalte struct with the class as template arg and a single static
+member fn. This fn has a member variable of type 'typeid sequence
+value'. The constructor of this type will automatically allocate the
+next free typeid integer. This can then efficiently be returned by the
+static retrieval function:
+
+    template <class T>
+    struct satcom::vtable::impl::TypeRegistry
+    {
+        static unsigned id() {
+            static satcom::vtable::impl::AutoTypeId typeid;
+            return typeid.id();
+        }
+    };
+
+    struct satcom::vtable::impl::AutoTypeId
+    {
+        AutoTypeId() : id(nextAutoTypeId()) {}
+        unsigned id;
+    };
+
+    unsigned nextAutoTypeId()
+    {
+        static unsigned id(0);
+        return id++;
+    }
+
+This setup will assign id's uniquely. The Id's will be ordered by the
+first TypeRegistry::id() call. To get the Type id of a type, just call
+satcom::vtable::impl::TypeRegistry<SomeType>::id().
+
+The above is bogus ... we don't register the extensible types, we
+register the extensions which are arbitrary types.
+
+The typeid assigned to the extension type is used as an index into a
+vtable. This vtable is in the simplest case, just an std::vector of
+void*. To assign an extension to a specific type, we just add some
+instance of the registered extension type to the vtable of the
+to-be-extended type using the slot given by the typeid of the
+extension type. To get the extension, we just look up the id of the
+extension type and cast the value from the vtable vector to the
+appropriate type. All this is O(1) and does not depend on the number
+of extensions or on the number of extended classes.
+
+The extension vtables are created inside a static method of a
+templated class (template arg is the extensible class). Additionally,
+the extensible class must CRTP-wise inherit the vtable baseclass,
+which will add a vtable pointer to the extensible class and initialize
+it automatically to point to the correct vtable.
+
+To make this even more efficient, all vtables should be kept in a
+list. This allows to keep all vtables to the same size. Then no range
+checking must be done on accessing the vtable, since all vtables are
+all as long as the largest extension id. This of course makes the
+Operation of registering a new extension type O(n), but that should
+not be a problem since extensions are registered once during program
+startup. As a reward, the lookup performance is increased: it is only
+a memory access to find the extension-type id(the address is fixed at
+compile time) followed by an indexed access to the vtable, where the
+vtable address is fetched using another memory access. This differs
+from a compiler-generated vtable access only by a single memory
+access.
diff --git a/Packets/GenericPacket.ct b/Packets/GenericPacket.ct
new file mode 100644 (file)
index 0000000..842fa56
--- /dev/null
@@ -0,0 +1,57 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+//#include "GenericPacket.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ void satcom::pkf::GenericPacket<HEADER,TRAILER>::v_nextInterpreter()
+    const
+{
+    this->registerInterpreter<DataPacket>(this->end_header(), this->begin_trailer());
+}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ void satcom::pkf::GenericPacket<HEADER,TRAILER>::v_finalize()
+{}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ void satcom::pkf::GenericPacket<HEADER,TRAILER>::v_dump(std::ostream & os)
+    const
+{
+    // TODO: implement v_dump()
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/GenericPacket.cti b/Packets/GenericPacket.cti
new file mode 100644 (file)
index 0000000..92c9e59
--- /dev/null
@@ -0,0 +1,98 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "GenericPacket.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <unsigned HEADER, unsigned TRAILER>
+template <class Arg>
+prefix_ satcom::pkf::GenericPacket<HEADER,TRAILER>::GenericPacket(Arg const & arg)
+: Packet(arg)
+{}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ void satcom::pkf::GenericPacket<HEADER,TRAILER>::init()
+{
+    insert(begin(),HEADER,0);
+    insert(end(),TRAILER,0);
+}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ typename satcom::pkf::GenericPacket<HEADER,TRAILER>::iterator
+satcom::pkf::GenericPacket<HEADER,TRAILER>::begin_header()
+    const
+{
+    return this->begin();
+}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ typename satcom::pkf::GenericPacket<HEADER,TRAILER>::iterator
+satcom::pkf::GenericPacket<HEADER,TRAILER>::end_header()
+    const
+{
+    return this->begin() + HEADER;
+}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ typename satcom::pkf::GenericPacket<HEADER,TRAILER>::size_type
+satcom::pkf::GenericPacket<HEADER,TRAILER>::header_len()
+{
+    return HEADER;
+}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ typename satcom::pkf::GenericPacket<HEADER,TRAILER>::iterator
+satcom::pkf::GenericPacket<HEADER,TRAILER>::begin_trailer()
+    const
+{
+    return this->end() - TRAILER;
+}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ typename satcom::pkf::GenericPacket<HEADER,TRAILER>::iterator
+satcom::pkf::GenericPacket<HEADER,TRAILER>::end_trailer()
+    const
+{
+    return this->end();
+}
+
+template <unsigned HEADER, unsigned TRAILER>
+prefix_ typename satcom::pkf::GenericPacket<HEADER,TRAILER>::size_type
+satcom::pkf::GenericPacket<HEADER,TRAILER>::trailer_len()
+{
+    return TRAILER;
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/GenericPacket.hh b/Packets/GenericPacket.hh
new file mode 100644 (file)
index 0000000..c8cd5d8
--- /dev/null
@@ -0,0 +1,91 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_GenericPacket_
+#define HH_GenericPacket_ 1
+
+// Custom includes
+#include "Packet.hh"
+
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+
+    /** \brief General packet comprised of header, trailer and payload
+
+        This class implements a generic packet with three sections: a
+        header, a trailer and a payload section. The header and
+        trailer are not interpreted in any way. The payload can be
+        manually chained to any packet interpreter.
+      */
+    template <unsigned HEADER, unsigned TRAILER=0>
+    class GenericPacket : public Packet
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef typename Packet::ptr_t<GenericPacket>::ptr ptr;
+        typedef iterator byte_iterator;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        void init();
+
+        iterator begin_header() const;
+        iterator end_header() const;
+        static size_type header_len();
+
+        iterator begin_trailer() const;
+        iterator end_trailer() const;
+        static size_type trailer_len();
+
+        static bool check(iterator const & b, iterator const & e) 
+            { return unsigned(e - b) >= HEADER + TRAILER; }
+        
+    protected:
+
+    private:  
+        template <class Arg>
+        GenericPacket(Arg const & arg);
+
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+        virtual void v_dump(std::ostream & os) const;
+
+        friend class Packet;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "GenericPacket.cci"
+#include "GenericPacket.ct"
+#include "GenericPacket.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/IpV4Packet.cc b/Packets/IpV4Packet.cc
new file mode 100644 (file)
index 0000000..095a2f9
--- /dev/null
@@ -0,0 +1,83 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "IpV4Packet.hh"
+//#include "IpV4Packet.ih"
+#include "EthernetPacket.hh"
+
+// Custom includes
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    namespace pkf = satcom::pkf;
+    pkf::PacketRegistry<pkf::EtherTypes>::RegistrationProxy<pkf::IpV4Packet> 
+        registerIpV4Packet(0x0800);
+}
+
+prefix_ void satcom::pkf::IpV4Packet::v_nextInterpreter()
+    const
+{
+    registerInterpreter(protocol(),begin()+bytes(),end());
+}
+
+prefix_ void satcom::pkf::IpV4Packet::v_finalize()
+{}
+
+prefix_ void satcom::pkf::IpV4Packet::v_dump(std::ostream & os)
+    const
+{
+    struct in_addr in;
+    in.s_addr = htonl(source());
+    std::string src (inet_ntoa(in));
+    in.s_addr = htonl(destination());
+    std::string dst (inet_ntoa(in));
+    os << "Internet protocol Version 4:\n"
+       << "  version       : " << version() << "\n"
+       << "  IHL           : " << ihl() << "\n"
+       << "  TOS           : " << unsigned(tos()) << "\n"
+       << "  length        : " << length() << "\n"
+       << "  identifier    : " << identifier() << "\n"
+       << "  DF            : " << df() << "\n"
+       << "  MF            : " << mf() << "\n"
+       << "  fragment      : " << frag() << "\n"
+       << "  TTL           : " << unsigned(ttl()) << "\n"
+       << "  protocol      : " << unsigned(protocol()) << "\n"
+       << "  CRC           : " << std::hex << crc() << std::dec << "\n"
+       << "  source        : " << src << "\n"
+       << "  destination   : " << dst << "\n";
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/IpV4Packet.cti b/Packets/IpV4Packet.cti
new file mode 100644 (file)
index 0000000..9a8c96f
--- /dev/null
@@ -0,0 +1,46 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "IpV4Packet.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Arg>
+prefix_ satcom::pkf::IpV4Packet::IpV4Packet(Arg const & arg)
+    : Packet(arg)
+{}
+
+
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/IpV4Packet.hh b/Packets/IpV4Packet.hh
new file mode 100644 (file)
index 0000000..0f9e296
--- /dev/null
@@ -0,0 +1,119 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_IpV4Packet_
+#define HH_IpV4Packet_ 1
+
+// Custom includes
+#include "Packet.hh"
+#include "ParseInt.hh"
+#include "ParseArray.hh"
+#include "PacketRegistry.hh"
+
+//#include "IpV4Packet.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+    
+    template <class Iterator=nil, class IpV4Packet=nil>
+    struct Parse_IpV4 : public ParserBase<Iterator,IpV4Packet>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_IpV4<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        Parse_IpV4() {}
+        Parse_IpV4(Iterator const & i) : ParserBase<Iterator,IpV4Packet>(i) {}
+
+        static unsigned bytes() { return 20; }
+        
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef Parse_UIntField <  0,  4, Iterator > Parse_Version;
+        typedef Parse_UIntField <  4,  8, Iterator > Parse_IHL;
+        typedef Parse_UInt8     <         Iterator > Parse_8bit;
+        typedef Parse_UInt16    <         Iterator > Parse_16bit;
+        typedef Parse_Flag      <  0,     Iterator > Parse_R;
+        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;  
+        
+        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_16bit    length()      const { return Parse_16bit   (this->i() + 2  ); }
+        Parse_16bit    identifier()  const { return Parse_16bit   (this->i() + 4  ); }
+        Parse_R        reserved()    const { return Parse_R       (this->i() + 6  ); }
+        Parse_DF       df()          const { return Parse_DF      (this->i() + 6  ); }
+        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_32bit    destination() const { return Parse_32bit   (this->i() + 16 ); }
+    };
+
+    struct IpV4Types {
+        typedef boost::uint16_t key_t;
+    };
+
+    class IpV4Packet
+        : public Packet, 
+          public Parse_IpV4<Packet::iterator,IpV4Packet>, 
+          public PacketRegistryMixin<IpV4Types,IpV4Packet>
+    {
+        using PacketRegistryMixin<IpV4Types,IpV4Packet>::registerInterpreter;
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<IpV4Packet>::ptr ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    private:
+        template <class Arg>
+        IpV4Packet(Arg const & arg);
+
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+        virtual void v_dump(std::ostream & os) const;
+
+        friend class Packet;
+    };
+}}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include IpV4Packet.cci"
+//#include "IpV4Packet.ct"
+#include "IpV4Packet.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/IpV4Packet.test.cc b/Packets/IpV4Packet.test.cc
new file mode 100644 (file)
index 0000000..fd93c5a
--- /dev/null
@@ -0,0 +1,110 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "IpV4Packet.test.hh"
+//#include "IpV4Packet.test.ih"
+
+// Custom includes
+#include "IpV4Packet.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+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
+                           };                        
+
+    typedef unsigned char * iterator;
+    Parse_IpV4<iterator> p(data);
+
+    BOOST_CHECK_EQUAL( p.version(),     0x00u       );
+    BOOST_CHECK_EQUAL( p.ihl(),         0x01u       );
+    // the static_cast is to silence gcc-3.3
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p.tos()), 0x02u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p.length()), 0x0304u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p.identifier()), 0x0506u );
+    BOOST_CHECK_EQUAL( p.reserved(),    0           );
+    BOOST_CHECK_EQUAL( p.df(),          0           );
+    BOOST_CHECK_EQUAL( p.mf(),          0           );
+    BOOST_CHECK_EQUAL( p.frag(),        0x0708u     );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p.ttl()), 0x09u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p.protocol()), 0x0Au );
+    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
+                           };  
+
+    IpV4Packet::ptr p (Packet::create<IpV4Packet>(data, data+sizeof(data)));
+
+    BOOST_CHECK_EQUAL( p->version(),     0x00u       );
+    BOOST_CHECK_EQUAL( p->ihl(),         0x01u       );
+    // the static_cast is to silence gcc-3.3
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p->tos()), 0x02u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p->length()), 0x0304u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p->identifier()), 0x0506u );
+    BOOST_CHECK_EQUAL( p->reserved(),    0           );
+    BOOST_CHECK_EQUAL( p->df(),          0           );
+    BOOST_CHECK_EQUAL( p->mf(),          0           );
+    BOOST_CHECK_EQUAL( p->frag(),        0x0708u     );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p->ttl()), 0x09u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p->protocol()), 0x0Au );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p->crc()), 0x0B0Cu );
+    BOOST_CHECK_EQUAL( p->source(),      0x11121314u );
+    BOOST_CHECK_EQUAL( p->destination(), 0x15161718u );
+
+
+}
+
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Packet.cc b/Packets/Packet.cc
new file mode 100644 (file)
index 0000000..c94f036
--- /dev/null
@@ -0,0 +1,295 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "Packet.hh"
+#include "Packet.ih"
+
+// Custom includes
+#include <boost/utility.hpp> // for next/prior
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// REFERENCE COUNTING
+///////////////////////////////////////////////////////////////////////////
+
+// We manage TWO reference counts:
+//
+// - The first reference counts lives wihin PacketImpl. It counts the
+//   number of references to the PacketImpl instance
+//
+// - The second reference count lives with the Packet interpreters. It
+//   counts the number of external references to the Packet facades.
+//
+// The PacketImpl refcount is always the sum of all it's Packet
+// interpreter member refcounts.
+//
+// The Packet facades are referenced from two sides:
+//
+// - From the user. These references are counted in the Packet
+//   refcount.
+//
+// - From the list of interpreters. These references are *not*
+//   counted.
+//
+// The Packet facades have an impl_ member. This is set to non-0 only,
+// as long as the Packet is a list member. The Packet may be deleted,
+// when impl_ == 0 and refcount_ == 0.
+
+// class ListPacketDeleter
+
+// This is the custom deleter used for the pointers in the
+// interpreters list. This deleter is only called, when the Packet is
+// removed from the interpreters list.
+prefix_ void satcom::pkf::impl::ListPacketDeleter::operator()(Packet * p)
+{
+    PacketImpl * impl = PacketImpl::impl(p);
+    if (impl->releaseInterpreter(p))
+        delete impl;
+}
+
+// struct PacketImpl
+
+prefix_ satcom::pkf::Packet::interpreter_list::iterator
+satcom::pkf::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;
+    this->interpreters_.push_back(
+        boost::shared_ptr<Packet>(p, impl::ListPacketDeleter()));
+
+    p->self_ = boost::prior(this->interpreters_.end());
+    return p->self_;
+}
+
+prefix_ satcom::pkf::Packet::interpreter_list::iterator
+satcom::pkf::impl::PacketImpl::prependInterpreter(Packet * p)
+{
+    BOOST_ASSERT( p->impl_ == 0 );
+
+    this->refcount_ += p->refcount_;
+    SATCOM_PKF_REFC_MSG("] PacketImpl::prependInterpreter (" << this << "): refcount_ = " << refcount_ << "\n");
+    p->impl_ = this;
+    this->interpreters_.push_front(
+        boost::shared_ptr<Packet>(p, pkf::impl::ListPacketDeleter()));
+
+    p->self_ = this->interpreters_.begin();
+    return p->self_;
+}
+
+// Called, whenever a Packet is removed from the list by the
+// ListPacketDeleter;
+prefix_ bool satcom::pkf::impl::PacketImpl::releaseInterpreter(Packet * p)
+{
+    // We have to be extra careful here: This method might be called
+    // AFTER the PacketImpl instance has already been destructed while
+    // destructing the interpreters list !!
+    // If p->refcount_ is > 0 however we know, that this->refcount_
+    // must also be > 0 ...
+    // So we have to make sure never to access this if p->refcount_==0
+    BOOST_ASSERT( p->impl_ == this );
+    bool rv (false);
+    if (p->refcount_ > 0) {
+        this->refcount_ -= p->refcount_;
+        rv = !this->refcount_;
+        SATCOM_PKF_REFC_MSG("] PacketImpl::releaseInterpreter (" << this << "): refcount_ = " << refcount_ << "\n");
+    }
+    if (p->unlink())
+        delete p;
+    return rv;
+}
+
+namespace {
+    bool whenceCmp(unsigned a, unsigned b, bool end, satcom::pkf::Packet::Whence whence)
+    {
+        using satcom::pkf::Packet;
+        return ((whence == Packet::OUTSIDE && ! end)
+                || whence == Packet::BEFORE
+                || (whence == Packet::INSIDE && end)) ? a>=b : a>b;
+    }
+}
+
+prefix_ void
+satcom::pkf::impl::PacketImpl::updateIterators(Packet::size_type index,
+                                               Packet::difference_type n,
+                                               Packet::interpreter_list::iterator self,
+                                               Packet::Whence whence)
+{
+    Packet::interpreter_list::iterator i (interpreters_.begin());
+    Packet::interpreter_list::iterator const e (interpreters_.end());
+    Packet::Whence w (whence == Packet::AUTO ? Packet::INSIDE : whence);
+    for (;i!=e;++i) {
+        if (whenceCmp((*i)->end_,index,true,w))
+            if (n<0 && (*i)->end_ < index-n)
+                (*i)->end_ = index;
+            else
+                (*i)->end_ += n;
+        if (whenceCmp((*i)->begin_,index,false,w))
+            if (n<0 && (*i)->begin_ < index-n)
+                (*i)->begin_ = index;
+            else
+                (*i)->begin_ += n;
+        if (i == self && whence == Packet::AUTO) w = Packet::OUTSIDE;
+        BOOST_ASSERT( (*i)->end_ >= (*i)->begin_ );
+    }
+}
+
+prefix_ void satcom::pkf::impl::PacketImpl::packet_add_ref(Packet const * p)
+{
+    p->add_ref();
+    if (p->impl_)
+        p->impl_->add_ref();
+}
+
+prefix_ void satcom::pkf::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
+        // however get deleted now.
+        delete p->impl_;
+    if (del)
+        delete p;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// class Packet
+
+prefix_ satcom::pkf::Packet::ptr satcom::pkf::Packet::next()
+    const
+{
+    interpreter_list::iterator n = boost::next(this->self_);
+    if (n == this->impl_->interpreters_.end()) {
+        if (this->parsed_)
+            return ptr(0);
+        // FIXME: v_nextInterpreter return bool? new Interpreter to be
+        // added ? hmm ... this however is quite suboptimal ...
+        this->v_nextInterpreter();
+        this->parsed_ = true;
+        n = boost::next(this->self_);
+        if (n == this->impl_->interpreters_.end())
+            return ptr(0);
+    }
+    // Re-converting the Packet to a smart pointer is correct here,
+    // since the shared_ptr really uses the intrusive refcount which
+    // makes this operation safe ...
+    return ptr(n->get(),true);
+}
+
+prefix_ satcom::pkf::Packet::ptr satcom::pkf::Packet::last()
+    const
+{
+    Packet * p = this->impl_->interpreters_.back().get();
+    while (! p->parsed_) {
+        Packet * pp = p->next().get();
+        if (pp) p = pp;
+    }
+    // Re-converting the to a smart pointer is correct here, since the
+    // shared_ptr really uses the intrusive refcount which makes this
+    // operation safe ...
+    return ptr(p,true);
+}
+
+prefix_ void satcom::pkf::Packet::i_registerInterpreter(Packet * p)
+    const
+{
+    BOOST_ASSERT( !p->impl_ );
+    this->impl_->truncateInterpretersAfter(this);
+    this->impl_->appendInterpreter(p);
+    this->parsed_ = true;
+}
+
+prefix_ void satcom::pkf::Packet::i_replaceInterpreter(Packet * p)
+{
+    BOOST_ASSERT( !p->impl_ );
+    // We need to increment the refcount of impl_ beforehand,
+    // otherwise it might get deleted by the truncateInterpreters call
+    boost::intrusive_ptr<impl::PacketImpl> impl (this->impl_,true);
+    impl->truncateInterpreters(this);
+    impl->appendInterpreter(p);
+}
+
+prefix_ void satcom::pkf::Packet::i_setInterpreter(impl::PacketImpl * i)
+{
+    // Using prependInterpreter makes this usable for both, the
+    // create-from-data and wrap-packet constructors
+    i->prependInterpreter(this);
+}
+
+prefix_ void satcom::pkf::Packet::insert(iterator pos, byte v, Whence whence)
+{
+    size_type index(pos-impl_->data_.begin());
+    BOOST_ASSERT( index >= begin_ && index <= end_);
+    impl_->data_.insert(pos,v);
+    impl_->updateIterators(index,1,self_,whence);
+}
+
+prefix_ void satcom::pkf::Packet::insert(iterator pos, size_type n, byte v, Whence whence)
+{
+    size_type index(pos-impl_->data_.begin());
+    BOOST_ASSERT( index >= begin_ && index <= end_ );
+    impl_->data_.insert(pos,n,v);
+    impl_->updateIterators(index,n,self_,whence);
+}
+
+prefix_ void satcom::pkf::Packet::erase(iterator pos)
+{
+    size_type index(pos-impl_->data_.begin());
+    BOOST_ASSERT( index >= begin_ && index < end_ );
+    impl_->data_.erase(pos);
+    impl_->updateIterators(index,-1,self_,INSIDE);
+}
+
+prefix_ void satcom::pkf::Packet::erase(iterator first, iterator last)
+{
+    size_type index(first-impl_->data_.begin());
+    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 ...
+    impl_->data_.erase(first,last);
+    impl_->updateIterators(index,-sz,self_,INSIDE);
+}
+
+prefix_ void satcom::pkf::Packet::dump(std::ostream & os)
+    const
+{
+    v_dump(os);
+    ptr p (next());
+    if (p)
+        p->dump(os);
+}
+
+//////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Packet.cci b/Packets/Packet.cci
new file mode 100644 (file)
index 0000000..c3262ea
--- /dev/null
@@ -0,0 +1,195 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+#include "Packet.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ satcom::pkf::impl::PacketImpl::PacketImpl()
+    : data_(), interpreters_(), refcount_(1)
+{
+    SATCOM_PKF_REFC_MSG("] PacketImpl::PacketImpl (" << this << "): refcount_ = 1\n");
+}
+
+prefix_ satcom::pkf::impl::PacketImpl::PacketImpl(unsigned size, Packet::byte initValue)
+    : data_(size,initValue), interpreters_(), refcount_(1)
+{
+    SATCOM_PKF_REFC_MSG("] PacketImpl::PacketImpl (" << this << "): refcount_ = 1\n");
+}
+
+prefix_ satcom::pkf::impl::PacketImpl::~PacketImpl()
+{
+    BOOST_ASSERT( !refcount_ );
+    SATCOM_PKF_REFC_MSG("] PacketImpl::~PacketImpl (" << this << ")\n");
+}
+
+// PacketImpl::add_ref and PacketImpl::release are only called from
+// intrusive_ptr_add_ref and intrusive_ptr_release
+prefix_ void satcom::pkf::impl::PacketImpl::add_ref()
+{ 
+    ++refcount_;
+    SATCOM_PKF_REFC_MSG("] PacketImpl::add_ref (" << this << "): refcount_ = " << refcount_ << "\n");
+}
+
+prefix_ bool satcom::pkf::impl::PacketImpl::release()
+{ 
+    BOOST_ASSERT( refcount_ > 0 );
+    --refcount_;
+    SATCOM_PKF_REFC_MSG("] PacketImpl::release (" << this << "): refcount_ = " << refcount_ << "\n");
+    return ! refcount_;
+}
+
+prefix_ void satcom::pkf::impl::PacketImpl::truncateInterpreters(Packet const * p)
+{
+    BOOST_ASSERT( p->impl_ == this );
+    this->interpreters_.erase(p->self_,this->interpreters_.end());
+}
+
+prefix_ void satcom::pkf::impl::PacketImpl::truncateInterpretersAfter(Packet const * p)
+{
+    BOOST_ASSERT( p->impl_ == this );
+    this->interpreters_.erase(boost::next(p->self_),this->interpreters_.end());
+}
+
+prefix_ satcom::pkf::impl::PacketImpl* satcom::pkf::impl::PacketImpl::impl(Packet const * p)
+{
+    return p->impl_;
+}
+
+/*
+prefix_ std::ostream & satcom::pkf::operator<<(std::ostream & os, Packet const & packet)
+{
+    packet.dump(os);
+    return os;
+}
+*/
+
+// These methods are called by the user codes Packet::ptr's. They
+// refcount both the Packet and the owning PacketImpl. 
+prefix_ void satcom::pkf::intrusive_ptr_add_ref(Packet const * p)
+{
+    impl::PacketImpl::packet_add_ref(p);
+}
+
+prefix_ void satcom::pkf::intrusive_ptr_release(Packet * p)
+{
+    impl::PacketImpl::packet_release(p);
+}
+
+prefix_ void satcom::pkf::impl::intrusive_ptr_add_ref(PacketImpl * p)
+{
+    p->add_ref();
+}
+
+prefix_ void satcom::pkf::impl::intrusive_ptr_release(PacketImpl * p)
+{
+    if (p->release())
+        delete p;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// class Packet
+
+prefix_ satcom::pkf::Packet::iterator satcom::pkf::Packet::begin()
+    const
+{
+    return impl_->data_.begin()+begin_;
+}
+
+prefix_ satcom::pkf::Packet::iterator satcom::pkf::Packet::end()
+    const
+{
+    return impl_->data_.begin()+end_;
+}
+
+prefix_ size_t satcom::pkf::Packet::size()
+    const
+{
+    return end_-begin_;
+}
+
+prefix_ satcom::pkf::Packet::ptr satcom::pkf::Packet::prev()
+    const
+{
+    if (this->self_ == this->impl_->interpreters_.begin())
+        return ptr(0);
+    // Re-converting the to a smart pointer is correct here, since the
+    // shared_ptr really uses the intrusive refcount which makes this
+    // operation safe ...
+    return ptr(boost::prior(this->self_)->get(),true);
+}
+
+prefix_ satcom::pkf::Packet::ptr satcom::pkf::Packet::head()
+    const
+{
+    // Re-converting the to a smart pointer is correct here, since the
+    // shared_ptr really uses the intrusive refcount which makes this
+    // operation safe ...
+    return ptr(this->impl_->interpreters_.front().get(),true);
+}
+
+prefix_  satcom::pkf::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
+    // BOOST_ASSERT( !this->refcount_  && !this->impl_ );
+    SATCOM_PKF_REFC_MSG("] Packet::~Packet (" << this << ")\n");
+}
+
+prefix_ void satcom::pkf::Packet::add_ref()
+    const
+{
+    ++this->refcount_;
+    SATCOM_PKF_REFC_MSG("] Packet::add_ref (" << this << "): refcount_ = " << this->refcount_ << "\n");
+}
+
+prefix_ bool satcom::pkf::Packet::release()
+{
+    BOOST_ASSERT( this->refcount_ > 0 );
+    --this->refcount_;
+    SATCOM_PKF_REFC_MSG("] Packet::release (" << this << "): refcount_ = " << this->refcount_ << "\n");
+    return !this->refcount_ && !this->impl_;
+}
+
+prefix_ bool satcom::pkf::Packet::unlink()
+{
+    SATCOM_PKF_REFC_MSG("] Packet::unlink (" << this << "): refcount_ = " << this->refcount_ << "\n");
+    this->impl_ = 0;
+    this->begin_ = this->end_;
+    return !this->refcount_;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Packet.ct b/Packets/Packet.ct
new file mode 100644 (file)
index 0000000..edc6518
--- /dev/null
@@ -0,0 +1,152 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+#include "Packet.ih"
+
+// Custom includes
+#include <algorithm>
+#include "ParserBase.hh"
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class OtherPacket, class InputIterator>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr
+satcom::pkf::Packet::create(InputIterator b, InputIterator e)
+{
+    boost::intrusive_ptr<impl::PacketImpl> impl (new impl::PacketImpl(b,e),false);
+    if (!check<OtherPacket>(impl->data_.begin(),impl->data_.end()))
+        throw TruncatedPacketException();
+    typename ptr_t<OtherPacket>::ptr p (new OtherPacket(PacketOp_set(impl.get())), false);
+    return p;
+}
+
+template <class OtherPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr satcom::pkf::Packet::create()
+{
+    boost::intrusive_ptr<impl::PacketImpl> impl (
+        new impl::PacketImpl(min_bytes<OtherPacket>(),0));
+    typename ptr_t<OtherPacket>::ptr p (new OtherPacket(PacketOp_set(impl.get())), false);
+    p->init();
+    return p;
+}
+
+template <class OuterPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OuterPacket>::ptr
+satcom::pkf::Packet::create(Packet::ptr payload)
+{
+    // TODO: should I instead of using head() throw away all
+    // 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();
+    return p;
+}
+
+template <class OtherPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr satcom::pkf::Packet::reinterpret()
+{
+    // THIS INVALIDATES this !!!!!!!
+    if (!check<OtherPacket>(begin(),end()))
+        throw TruncatedPacketException();
+    typename ptr_t<OtherPacket>::ptr p (new OtherPacket(PacketOp_replace(this)),false);
+    return p;
+}
+
+template <class OtherPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr
+satcom::pkf::Packet::registerInterpreter(raw_container::iterator begin,
+                                         raw_container::iterator end)
+    const
+{
+    if (!check<OtherPacket>(begin,end))
+        throw TruncatedPacketException();
+    typename ptr_t<OtherPacket>::ptr p (
+        new OtherPacket(PacketOp_register(begin-impl_->data_.begin(),
+                                         end-impl_->data_.begin(),
+                                         this)),
+        false);
+    return p;
+}
+
+#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Packets/Packet.mpp", 4))
+#include BOOST_PP_ITERATE()
+
+template <class OtherPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr satcom::pkf::Packet::find_next()
+    const
+{
+    ptr p (next());
+    while (p && !p->is<OtherPacket>())
+        p = p->next();
+    return p->as<OtherPacket>();
+}
+
+template <class OtherPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr satcom::pkf::Packet::find_prev()
+    const
+{
+    ptr p (prev());
+    while (p && !p->is<OtherPacket>())
+        p = p->prev();
+    return p->as<OtherPacket>();
+}
+
+template <class OtherPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr satcom::pkf::Packet::get_next()
+    const
+{
+    typename ptr_t<OtherPacket>::ptr p (find_next<OtherPacket>());
+    BOOST_ASSERT(p);
+    return p;
+}
+
+template <class OtherPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr satcom::pkf::Packet::get_prev()
+    const
+{
+    typename ptr_t<OtherPacket>::ptr p (find_prev<OtherPacket>());
+    BOOST_ASSERT(p);
+    return p;
+}
+
+template <class InputIterator>
+prefix_ void satcom::pkf::Packet::insert(iterator pos, InputIterator f, InputIterator l,
+                                         Whence whence)
+{
+    size_type index(pos-impl_->data_.begin());
+    BOOST_ASSERT( index >= begin_ && index <= end_ );
+    size_type sz (impl_->data_.size());
+    impl_->data_.insert(pos,f,l);
+    impl_->updateIterators(index,impl_->data_.size()-sz,self_,whence);
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Packet.cti b/Packets/Packet.cti
new file mode 100644 (file)
index 0000000..364bd17
--- /dev/null
@@ -0,0 +1,73 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+#include "Packet.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <typename OtherPacket>
+prefix_ bool satcom::pkf::Packet::is()
+    const
+{
+    return dynamic_cast<OtherPacket const *>(this);
+}
+
+template <typename OtherPacket>
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr satcom::pkf::Packet::as()
+{
+    return typename ptr_t<OtherPacket>::ptr(dynamic_cast<OtherPacket*>(this),true);
+}
+
+// This constructor appends a new interreter to the interpreter chain
+// of an existing Packet
+template <class Operation>
+prefix_ satcom::pkf::Packet::Packet(Operation const & arg)
+    : impl_(0), begin_(arg.begin()), end_(arg.end()), self_(),
+      parsed_(false), refcount_(1)
+{
+    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.
+    arg(this);
+}
+
+template <class InputIterator>
+prefix_ satcom::pkf::impl::PacketImpl::PacketImpl(InputIterator begin, InputIterator end)
+    : data_(begin, end), interpreters_(), refcount_(1)
+{
+    SATCOM_PKF_REFC_MSG("] PacketImpl::PacketImpl (" << this << "): refcount_ = 1\n")
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Packet.hh b/Packets/Packet.hh
new file mode 100644 (file)
index 0000000..ef25f14
--- /dev/null
@@ -0,0 +1,706 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// TODO: Implement assign() method akin to reinterpret(). However,
+// instead of using the data already present, assign() will replace
+// the date of the current packet with the given Packet.
+
+// TODO: Implement wrapping-constructor. Somehow we want to have a
+// constructor, which allows creating a chain of packet interpreters
+// with as little overhead as possible.
+
+// TODO: Document the additional concrete Packet facade requirements
+// explicitly and not only within the Parser requirements (check(),
+// bytes() and min_bytes() members ...)
+
+// TODO: Implement special container replacing vector which manages
+// some headroom to allow efficient insertion of elements at the
+// beginning. This really is just another type of deque
+// implementation.
+
+
+/** \mainpage The SatCom Packet Framework
+
+    \section arch Overall Architecture
+
+    The general Architecture of the Packet Framework (pkf for short)
+    is seperated into two components: The basic packet handling and
+    the parser framework.
+
+    The basic packet handling implements a packet interpreter
+    chain. Every packet is represented as a chain of interpreters
+    where each interpreter is a facade looking into the same
+    packet. Each interpreter will interpret a specific header of a
+    packet. For example, an ethernet frame might have an interpreter
+    chain consisting of EthernetPacket, IPPacket, UDPPacket and
+    DataPacket. Each of these interpreters will interpret a section of
+    the raw data bytes. The interpreter ranges overlap since every
+    packet also includes it's payload.
+
+    The parser framework is used to interpret the raw bytes of a
+    specific packet and parse the values present in that packet. For
+    example, Parse_Ethernet will parse the ethernet source MAC,
+    destination MAC and ethertype given any random access iterator to
+    the first byte of the ethernet frame. Parsers are extremely light
+    classes. They are temporary classes passed around by value. In
+    most cases, they are just comprised of a single pointer adorned
+    with type information.
+
+    \section handling Packet Handling
+
+    The packet handling is implemented within
+    satcom::pkf::Packet. This class is the baseclass to all packet
+    interpreter facades. To implement a new packet type, publically
+    derive from satcom::pkf::Packet and implement the virtual
+    interface (see the class documentation for details).
+
+    \section framework Parser Framework
+
+    The parser framework provides an abstract framwork to parse packet
+    oriented data. A Parser is a template class taking an arbitrary
+    iterator as input and allowing random access to data elements of
+    the interpreted type, like source and destination MAC of an
+    ethernet frame. The parser framework is to be used hierarchically
+    and recursively, the parser methods should return further parsers
+    which can return further parsers and so on.
+
+    The parser framework contains some basic parsers to be used to
+    build up more complex parsers:
+
+     - ParseInt.hh: Lots of parsers for integer numbers like
+       satcom::pkf::Parse_UInt8, for integer bitfields like
+       satcom::pkf::Parse_UIntField and satcom::pkf::Parse_Flag to
+       parse boolean flags.
+
+     - ParseArray.hh: The satcom::pkf::Parse_Array parser to parse
+       arbitrary fixed-size arrays of fixed-size elements (that is
+       sub-parsers).
+
+     - ParseVec.hh: The satcom::pkf::Parse_Vector parser to parse
+       dynamically sized arrays of fixed-size elements (that is
+       sub-parsers).
+
+    See satcom::pkf::ParserBase for further information.
+
+    \section stuff Other Utilities
+
+    The pkf also comprises some additional utilities to support the
+    development of packet classes. 
+
+    The satcom::pkf::PacketRegistry implements a registry of packets
+    keyed by an arbitrary type. The registry is used to find a packet
+    type given some kind of id (like the ethertype value from the
+    ethernet header). Together with it's support classes (especially
+    satcom::pkf::PacketRegistryMixin) this class greatly simplifies
+    implementing the needed table lookups.
+ */
+
+/** \file
+    \brief Main packet interface
+ */
+
+#ifndef HH_Packet_
+#define HH_Packet_ 1
+
+// Custom includes
+#include <boost/utility.hpp> // for boost::noncopyable
+#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <list>
+#include <vector>
+#include <iostream>
+
+#include "Packet.mpp"
+// ////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+    
+    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. satcom::pkf::Packet manages the necessary memory
+        resources and controlls the chain of packet interpreters.
+
+        The Packet user always interfaces with the pkf via a Packet
+        derived class. This is the only external entity ever held by a
+        library user. The interface is implemented using a reference
+        counted smart pointer, so resource management is quasi
+        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
+        according to the definition of that derived class's packet
+        type (i.e. EthernetPacket or UDPPacket).
+
+        Packet provides several interfaces:
+        
+        - Creation of Packet instances: create()
+
+        - Access to the chain of interpreters: next(), prev(), head(),
+          last(), find_next(), find_prev(), get_next(), get_prev(),
+          is(), as() and reinterpret()
+
+        - Access to the raw packet data: begin(), end(), size(),
+          insert() and erase()
+
+        - An interface to the derived class: v_nextInterpreter(),
+          v_finalize(), registerInterpreter()
+
+
+        \section packet_der Implementing new Packet facades
+
+        To implement a new Packet facade, publically derive from
+        Packet. You need to implement the following minimal interface:
+
+        - You need to provide a new #ptr typedef
+
+        - You have to implement v_nextInterpreter() and v_finalize()
+
+        - The constructor should be private
+
+        - You must make Packet a \c friend of the new Packet facade
+
+        - You must implement a static check() method which validates
+          a byte region as your new Packet
+
+        \code        
+            class ExamplePacket 
+                : public satcom::pkf::Packet
+            {
+            public:
+                typedef ptr_t<ExamplePacket>::ptr ptr;
+
+                static bool check(Packet::iterator begin, Packet::iterator end)
+                {
+                    // Validate, that the region [begin,end) can be
+                    // interpreted as an ExamplePacket without risking
+                    // memory access violations.
+                }
+
+            private:
+                template <class Arg>
+                ExamplePacket(Arg arg [, other args ... ])
+                    : satcom::pkf::Packet(arg)
+                {}
+
+                virtual void v_nextInterpreter() const
+                {
+                    // NextPacketType and header_length of course
+                    // depend on the packet type
+                    registerInterpreter<NextPacketType>(begin()+header_length, end());
+                }
+
+                virtual void v_finalize()
+                {
+                    // calculate checksum etc
+                }
+
+                friend class satcom::pkf::Packet;
+            };
+        \endcode
+
+        Please do not implement the methods inline to not clutter up
+        the header file. This is done here in the example to simplify
+        it. If a class is to be registered in some
+        satcom:pkf::PacketRegistry, it must not take any additional
+        constructor parameters.
+
+        After having implemented the bare framework, the most comman
+        way to implement access to the packets specific data is to use
+        the parser framework by additionally inheriting a
+        corresponding parser. This also automatically implements the
+        check() method, which is provided by the Parser.
+
+        In the following example we only show the differences from the
+        previous example:
+
+        \code
+            class ExamplePacket
+                : public satcom::pkf::Packet,
+                  public Parse_Example<satcom::pkf::Packet::iterator,
+                                       ExamplePacket>
+            {
+
+                // check does not need to be implemented here, it is
+                // inherited from the parser 
+
+            private:
+                template <class InputIterator>
+                ExamplePacket(InputIterator begin, InputIterator end)
+                    : satcom::pkf::Packet(begin,end)
+                {}
+            };
+        \endcode
+
+        See the satcom::pkf::ParserBase Documentation for how to
+        implement Parse_Example.
+
+        The implementation of v_nextInterpreter most of the time
+        relies on some packet registry. This is simplified using the
+        satcom::pkf::PacketRegistryMixin class as follows. Again, we
+        only show the differences from the preceding Example:
+
+        \code
+            struct ExampleRegistry {
+                type boost::uint16_t key_t;
+            };
+
+            class ExamplePacket
+                : public satcom::pkf::Packet,
+                  public Parse_Example<satcom::pkf::Packet::iterator,
+                                       ExamplePacket>,
+                  public satcom::pkf::PacketRegistryMixin<ExampleRegistry,
+                                                          ExamplePacket>
+            {
+                using satcom::pkf::Packet::registerInterpreter;
+                using satcom::pkf::PacketRegsitryMixin<ExampleRegistry,ExamplePacket>::registerInterpreter;
+            private:
+                virtual void v_nextInterpreter() const
+                {
+                    // nextType() is defined in Parse_Example and
+                    // returns the key in the ExampleRegistry of the
+                    // next Packet.
+                    registerInterpreter(nextType(),begin()+header_length, end());
+                }
+            };
+        \endcode
+
+        For further details on the packet registry, see
+        satcom::pkf::PacketRegistry.
+
+        \section packet_impl Implementation details
+
+        The Packet interface is implemented to minimize overhead as
+        far as possible without getting to complex. One area for
+        improvement ist the container class used to hold the raw
+        data. This currently is an \a std::vector. This could be
+        imporved by either allocating some headroom/tailroom in the
+        vector and using this when inserting data at the beginning or
+        end. Alternatively, a new container class (like the
+        satcom::lib::deque_list) could be used to support zero-copy
+        semantics.
+
+        At the moment, we leave the implementation at
+        std::vector. This container is very simple and especially it
+        can directly be sent out using the operating system since a \a
+        vector stores data at contiguous memory locations. An \a
+        std::deque could be used with \a writev(), however since we
+        have no access to the implementation details of the \a deque,
+        we cannot construct the \a writev() data structures.
+
+        The interpreter list managed by Packet is lazy, meaning packet
+        interpreter facades are added only when requestd by next(),
+        last() or find_next(). v_nextInterpreter() is called if
+        necessary by these methods to complete the interpreter chain.
+
+        To implement the automatic memory management, every Packet
+        facade is reference counted. Additionally, the number of
+        (indirect) references to PacketImpl is counted. This allows to
+        manage the PacketImpl instance automatically. To make this
+        work, it is necessary to ensure throughout the Packet code,
+        that the reference count of a Packet is not accidentally
+        decremented to zero. Also, the internal pointers from the
+        interpreter list to the Packet facades must not be
+        counted. They are therefore implemented differently (
+        boost::shared_ptr vs. boost::intrusive_ptr). The choice of
+        boost::intrusive_ptr for the externaly visible smart pointer
+        for all Packet facades is taken to reduce the overhead (an
+        intrusive_ptr is only the size of an ordinary pointer, a
+        smart_ptr has the size of two pointers).
+
+        \nosubgrouping
+      */
+    class Packet : boost::noncopyable
+    {
+    public:
+        ///\name Types
+        ///@{
+        typedef boost::uint8_t byte; //!< single byte datatype
+        ///@}
+
+    private:
+        ///\name Implementation
+        ///@{
+        // These types are implementation details. They are however
+        // needed to provide the correct typedefs for the user
+        // interface. Hiding these classes would incur a huge
+        // additional indirection overhead.
+
+        typedef std::vector<byte> raw_container;
+        typedef boost::shared_ptr<Packet> interpreter_list_ptr;
+        typedef std::list<satcom::pkf::Packet::interpreter_list_ptr> interpreter_list;
+        typedef unsigned refcount_t;
+
+        ///@}
+
+    public:
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\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.
+         */
+        template <class T> struct ptr_t { typedef boost::intrusive_ptr<T> ptr; };
+
+        /** \brief smart pointer to the Packet facades
+
+            Every derived class \e must redeclare this member for it's
+            derived type:
+            \code 
+                typedef ptr_t<DerivedClass>::ptr ptr
+            \endcode
+         */
+        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;
+
+        ///@}
+
+        // ////////////////////////////////////////////////////////////////////////
+
+        ///\name Creating packets
+        ///@{
+
+        /** \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.
+
+            \param OtherPacket Type of Packet to create, a Packet
+                    derived class
+            \param b begin iterator of byte range to create the Packet
+                    from
+            \param e corresponding end iterator
+            \return smart pointer to new packet
+            \throws TruncatedPacketException The data cannot be parsed
+                    securely (the data might be trunctated or just
+                    plain invalid)
+         */
+        template <class OtherPacket, class InputIterator>
+        static typename ptr_t<OtherPacket>::ptr create(InputIterator b, InputIterator e);
+
+        template <class OtherPacket>
+        static typename ptr_t<OtherPacket>::ptr create();
+
+        template <class OuterPacket>
+        static typename ptr_t<OuterPacket>::ptr create(Packet::ptr payload);
+
+        ///@}
+
+        ///\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 previous packet from the interpreter chain
+            \return smart pointer to previous packet or 0 if last packet */
+        ptr prev() const;
+        /** \brief first packet of the interpreter chain
+            \return smart pointer to first packet */
+        ptr head() 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 */
+        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr find_next() const;
+        /** \brief first packet of given type before the current packet
+            \return smart pointer to first preceding packet of type \a
+                OtherPacket or 0, if no such packet exists */
+        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr find_prev() const;
+
+        /** \brief first packet of given type after the current packet
+            \return smart pointer to first following packet of type \a
+            OtherPacket. \e Assert's, that a packet of this type exists */
+        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr get_next() const;
+        /** \brief first packet of given type before the current packet
+            \return smart pointer to first preceding packet of type \a
+            OtherPacket. \e Assert's, that a packet of this type exists */
+        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr get_prev() const;
+
+        /** \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; 
+        /** \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(); 
+
+        /** \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. 
+
+            \attention This invalidates the packet instance \e
+            this</b>. You must ensure, not to use the Packet instance
+            any further after this call
+
+            \return smart pointer to a \e new packet facade
+            \throws TruncatedPacketException there is not enough data
+                to savely interpret the packet as the given type. The
+                original packet is \e not invalidated
+         */
+        template <class OtherPacket>
+        typename ptr_t<OtherPacket>::ptr reinterpret();
+
+        ///@}
+
+        ///\name Raw packet data
+        ///@{
+
+        /** \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
+            payload of the packet, use next()->begin().
+
+            \return random access iterator to the begin of the raw
+                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
+            payload of the packet, use next()->end().
+
+            \return random access past-the-end iterator of the raw
+                data */
+        iterator end() const;
+        /** \brief raw data size of packet
+            \return size of the raw data interpreted by this
+                packet in bytes. This is \e not necessarily the size of
+                the complete packet, use head()->size() for this. */
+        size_t size() const;
+
+        // Modifying the raw packet data
+
+        // FIXME: Make all data mutators protected
+
+        typedef enum { AUTO, BEFORE, INSIDE, OUTSIDE, AFTER } Whence;
+
+        /** \brief insert single byte \a v before pos
+
+            \attention The change will \e not be validated by the
+            derived packet instance. This method is mostly to be used
+            by the derived class implementation and their helper
+            classes. */
+        void insert(iterator pos, byte v, Whence whence = AUTO);
+        /** \brief insert \a n copies of byte \a v before pos
+
+            \attention The change will \e not be validated by the
+            derived packet instance. This method is mostly to be used
+            by the derived class implementation and their helper
+            classes. */
+        void insert(iterator pos, size_type n, byte v, Whence whence = AUTO);
+        /** \brief insert a copy of the given range before pos
+
+            \attention The change will \e not be validated by the
+            derived packet instance. This method is mostly to be used
+            by the derived class implementation and their helper
+            classes. */
+        template <class InputIterator> 
+        void insert(iterator pos, InputIterator f, InputIterator l, Whence whence = AUTO);
+
+        /** \brief erase single byte
+
+            \attention The change will \e not be validated by the
+            derived packet instance. This method is mostly to be used
+            by the derived class implementation and their helper
+            classes. */
+        void erase(iterator pos);
+        /** \brief erase range
+
+            \attention The change will \e not be validated by the
+            derived packet instance. This method is mostly to be used
+            by the derived class implementation and their helper
+            classes. */
+        void erase(iterator first, iterator last);
+
+        ///@}
+
+        void dump(std::ostream & os) const;
+
+    protected:
+        ///\name Derived class interface
+        ///@{
+
+        /** \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
+            reinterpret() via the derived classes template
+            constructor.
+         */
+        template <class Operation>
+        Packet(Operation const & arg);
+        virtual ~Packet();
+        
+    private:
+        /** \brief create next packet interpreter
+
+            This method is called by next(), last() or find_next() to
+            create any missing interpreters in the interpreter
+            chain. This method must be overridden in the derived class
+            to register the next packet interpreter in the interpreter
+            chain with the packet framework.
+
+            To register the new interpreter, use
+            registerInterpreter() to create the new Packet
+            instance. The new instance is automatically added to the
+            interpreter chain after the current interpreter.
+
+            See also satcom::pkf::PacketRegistryMixin on how to
+            use a Registry to find the next interpreters implementing
+            class.
+         */
+        virtual void v_nextInterpreter() const = 0;
+
+        /** \brief finalize packet for sending
+
+            This method is called by the packet framework to let the
+            interpreter facade do some final calculations/packet
+            cleanup before the packet is sent out or digested in some
+            other way. This is the place to calcaulate checksums and
+            such.
+
+            This method is autmatically called for all interpreters on
+            the interpreter chain.
+         */
+        virtual void v_finalize() = 0;
+
+        virtual void v_dump(std::ostream & os) const = 0;
+
+    protected:
+        /** \brief add interpreter to interpreter chain
+
+            This method is used by v_nextInterpreter() in the derived
+            classes to add a new interpreter to the interpreter
+            chain. This method will call \c OtherPacket's constructor
+            with the correct arguments and insert the new interpreter
+            into the interpreter list. This method is used, if no
+            further arguments are to be passed to the \c OtherPacket
+            constructor. If additional arguments are necessary, just
+            add them after \c end. The compiler will then choose the
+            correct overload to use.
+         */
+        template <class OtherPacket>
+        typename ptr_t<OtherPacket>::ptr registerInterpreter(
+            raw_container::iterator begin, raw_container::iterator end) const;
+        template <class OtherPacket, class A0>
+        typename ptr_t<OtherPacket>::ptr registerInterpreter(
+            raw_container::iterator begin, raw_container::iterator end,
+            A0 const & a0) const;
+
+#       define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Packets/Packet.mpp", 3))
+#       include BOOST_PP_ITERATE()
+
+        ///@}
+
+    private:
+
+        ///\name Implementation
+        ///@{
+
+        void add_ref() const;
+        bool release();
+        bool unlink();
+
+       struct PacketOp_register;
+       friend class PacketOp_register;
+        void i_registerInterpreter(Packet * p) const;
+
+       struct PacketOp_replace;
+       friend class PacketOp_replace;
+        void i_replaceInterpreter(Packet * p);
+
+       struct PacketOp_set;
+       friend class PacketOp_set;
+        void i_setInterpreter(impl::PacketImpl * i);
+
+    private:
+        friend class impl::PacketImpl;
+        template <class OtherPacket> friend class impl::PkReg_EntryImpl;
+
+        impl::PacketImpl* impl_;
+        size_type begin_;
+        size_type end_;
+        interpreter_list::iterator self_;
+        mutable bool parsed_;
+        mutable refcount_t refcount_;
+
+        ///@}
+    };
+
+    /** \brief dump packet to stream
+        \related Packet */
+    // std::ostream & operator<<(std::ostream & os, Packet const & packet);
+
+    /** \brief smart pointer handling
+        \relates Packet */
+    void intrusive_ptr_add_ref(Packet const *);
+    /** \brief smart pointer handling
+        \relates Packet */
+    void intrusive_ptr_release(Packet *);
+
+    struct TruncatedPacketException : public std::exception
+    { virtual char const * what() const throw() { return "truncated packet"; } };
+
+}}
+
+// ////////////////////////////hh.e////////////////////////////////////////
+#include "Packet.cci"
+#include "Packet.ct"
+#include "Packet.cti"
+
+#include "Packet.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Packet.ih b/Packets/Packet.ih
new file mode 100644 (file)
index 0000000..1520385
--- /dev/null
@@ -0,0 +1,143 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_Packet_
+#define IH_Packet_ 1
+
+// Custom includes
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+#ifdef SATCOM_PKF_REFC_DEBUG
+#include <iostream>
+#define SATCOM_PKF_REFC_MSG(x) std::cerr << x
+#else
+#define SATCOM_PKF_REFC_MSG(x)
+#endif
+
+namespace satcom {
+namespace pkf {
+namespace impl {
+
+    // This deleter is used in the PacketImpl list holding the
+    // Packet's. It only decrements the Packet refcount. If this
+    // drops to 0 (i.e. the packet is removed from the list and no
+    // external reference exists) the packet ist deleted.
+    //
+    // Since this is called, when the packet is removed from the
+    // list, we set the impl_ member to 0 to mark, that the packet
+    // is now orphaned and every use should throw an exception ...
+    //
+    // To make this work we must make sure, that the packet
+    // refcount is incremented when we add the packet to the list.
+    struct ListPacketDeleter {
+        void operator()(Packet * p);
+    };
+
+    struct PacketImpl
+    {
+        Packet::raw_container data_;
+        Packet::interpreter_list interpreters_;
+        Packet::refcount_t refcount_;
+
+        PacketImpl();
+        PacketImpl(unsigned size, Packet::byte initValue);
+        ~PacketImpl();
+        template <class InputIterator>
+        PacketImpl(InputIterator begin, InputIterator end);
+
+        void add_ref();
+        bool release();
+
+        Packet::interpreter_list::iterator appendInterpreter(Packet * p);
+        Packet::interpreter_list::iterator prependInterpreter(Packet * p);
+        bool releaseInterpreter(Packet * p);
+        void truncateInterpreters(Packet const * p);
+        void truncateInterpretersAfter(Packet const * p);
+
+        void updateIterators(Packet::size_type index, Packet::difference_type n,
+                             Packet::interpreter_list::iterator self,
+                             Packet::Whence whence);
+
+        ///////////////////////////////////////////////////////////////////////////
+        // These are here to simplify the friend declaration in Packet
+
+        static void packet_add_ref(Packet const * p);
+        static void packet_release(Packet * p);
+        static PacketImpl* impl(Packet const * p);
+        static Packet::interpreter_list::iterator self(Packet const * p);
+    };
+
+    // These methods are used internally to keep PacketImpl_ alive during
+    // method invocations
+    void intrusive_ptr_add_ref(PacketImpl * p);
+    void intrusive_ptr_release(PacketImpl * p);
+}}}
+
+
+struct satcom::pkf::Packet::PacketOp_register
+{
+    size_type b;
+    size_type e;
+    const Packet * 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; }
+    void operator ()(Packet * self) const
+    { p->i_registerInterpreter(self); }
+};
+
+struct satcom::pkf::Packet::PacketOp_replace 
+{
+    Packet * p;
+
+    PacketOp_replace(Packet * p_) : p(p_) {}
+
+    size_type begin() const { return p->begin_; }
+    size_type end() const { return p->end_; }
+    void operator()(Packet * self) const
+    { p->i_replaceInterpreter(self); }
+};
+
+struct satcom::pkf::Packet::PacketOp_set
+{
+    impl::PacketImpl * i;
+
+    PacketOp_set(impl::PacketImpl * i_) : i(i_) {}
+
+    size_type begin() const { return 0; }
+    size_type end() const { return i->data_.size(); }
+    void operator()(Packet * self) const
+    { self->i_setInterpreter(i); }
+};
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Packet.mpp b/Packets/Packet.mpp
new file mode 100644 (file)
index 0000000..3d47d96
--- /dev/null
@@ -0,0 +1,134 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#if !BOOST_PP_IS_ITERATING
+
+// Custom includes
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/enum.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+#  ifndef MPP_Packet_
+#    define MPP_Packet_
+#    define pkARG(z,n,data) BOOST_PP_CAT(A,n) const & BOOST_PP_CAT(a,n)
+#  else
+#    undef pkARG
+#  endif
+
+#else
+//////////////////////////////mpp.p////////////////////////////////////////
+
+#if BOOST_PP_ITERATION_DEPTH()==1 && BOOST_PP_ITERATION_FLAGS()==1
+///////////////////////////////////////////////////////////////////////////
+// Packet::reinterpret member template declaration
+
+template < class OtherPacket, BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A) >
+typename ptr_t<OtherPacket>::ptr reinterpret( BOOST_PP_ENUM( BOOST_PP_ITERATION(), pkARG, ) );
+
+#elif BOOST_PP_ITERATION_DEPTH()==1 && BOOST_PP_ITERATION_FLAGS()==2
+///////////////////////////////////////////////////////////////////////////
+// Packet::reinterpret implementation
+
+template <class OtherPacket, BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A) >
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr
+satcom::pkf::Packet::reinterpret( BOOST_PP_ENUM( BOOST_PP_ITERATION(), pkARG, ) )
+{
+    if (!OtherPacket::check(begin(),end()))
+        throw TruncatedPacketException();
+    typename ptr_t<OtherPacket>::ptr p (
+        new OtherPacket(PacketOp_replace(this),
+                       BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a ) ),
+        false);
+    return p;
+}
+
+#elif BOOST_PP_ITERATION_DEPTH()==1 && BOOST_PP_ITERATION_FLAGS()==3
+///////////////////////////////////////////////////////////////////////////
+// Packet::registerInterpreter member template declaration
+
+template < class OtherPacket, BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A) >
+typename ptr_t<OtherPacket>::ptr registerInterpreter(
+    raw_container::iterator begin, raw_container::iterator end,
+    BOOST_PP_ENUM( BOOST_PP_ITERATION(), pkARG, ) ) const;
+
+#elif BOOST_PP_ITERATION_DEPTH()==1 && BOOST_PP_ITERATION_FLAGS()==4
+///////////////////////////////////////////////////////////////////////////
+// Packet::registerIterpreter implementation
+
+template <class OtherPacket, BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A) >
+prefix_ typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr
+satcom::pkf::Packet::registerInterpreter(raw_container::iterator begin,
+                                         raw_container::iterator end,
+                                         BOOST_PP_ENUM( BOOST_PP_ITERATION(), pkARG, ) )
+    const
+{
+    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) ),
+        false);
+    return p;
+}
+
+#elif BOOST_PP_ITERATION_DEPTH()==1 && BOOST_PP_ITERATION_FLAGS()==5
+///////////////////////////////////////////////////////////////////////////
+// Packet::create declaration
+
+template < class OtherPacket, class InputIterator, 
+           BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A) >
+static typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr create(
+    InputIterator b, InputIterator e,
+    BOOST_PP_ENUM( BOOST_PP_ITERATION(), pkARG, ) );
+
+#elif BOOST_PP_ITERATION_DEPTH()==1 && BOOST_PP_ITERATION_FLAGS()==6
+///////////////////////////////////////////////////////////////////////////
+// Packet::create implementation
+
+template < class OtherPacket, class InputIterator, 
+           BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A) >
+typename satcom::pkf::Packet::ptr_t<OtherPacket>::ptr satcom::pkf::Packet::create(
+    InputIterator b, InputIterator e,
+    BOOST_PP_ENUM( BOOST_PP_ITERATION(), pkARG, ) )
+{
+    boost::intrusive_ptr<impl::PacketImpl> impl (new impl::PacketImpl(b,e),false);
+    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) ),
+        false);
+    return p;
+}
+
+#endif
+
+//////////////////////////////mpp.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/Packet.test.cc b/Packets/Packet.test.cc
new file mode 100644 (file)
index 0000000..d41e8a0
--- /dev/null
@@ -0,0 +1,247 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "Packet.test.hh"
+//#include "Packet.test.ih"
+
+// Custom includes
+#include "Packet.hh"
+#include "DataPacket.hh"
+#include "GenericPacket.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+// Since Packet is abstract, we can only test the Packet interface using
+// a simple implementation: DataPacket and GenericPacket.
+
+namespace {
+
+    Packet::byte data[] = {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+                            10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
+
+    bool compare(Packet::iterator b, Packet::iterator e, unsigned o=0)
+    {
+        unsigned i (o);
+        for (; b!=e; ++b, ++i)
+            if (i>=sizeof(data) || *b != data[i])
+                return false;
+        return true;
+    }
+
+}
+        
+BOOST_AUTO_UNIT_TEST(Packet_DataPacket)
+{
+    Packet::ptr p (Packet::create<DataPacket>(data, data+sizeof(data)));
+
+    BOOST_REQUIRE( p );
+    BOOST_CHECK_EQUAL( p->size(), sizeof(data) );
+    BOOST_CHECK( compare(p->begin(), p->end()) );
+
+    *p->begin() = 20;
+    BOOST_CHECK( !compare(p->begin(), p->end()) );
+    BOOST_CHECK_EQUAL( *p->begin(), 20 );
+
+    BOOST_CHECK( !p->next() );
+    BOOST_CHECK( !p->prev() );
+    BOOST_CHECK_EQUAL( p->head(), p );
+    BOOST_CHECK_EQUAL( p->last(), p );
+
+    BOOST_CHECK( p->is<DataPacket>() );
+    BOOST_CHECK( p->as<DataPacket>() );
+}
+
+BOOST_AUTO_UNIT_TEST(Packet_GenericPacket)
+{
+    GenericPacket<4,6>::ptr p (Packet::create< GenericPacket<4,6> >(data, data+sizeof(data)));
+
+    // check, that the packet was constructed corretly
+    BOOST_REQUIRE( p );
+    BOOST_CHECK_EQUAL( p->size(), sizeof(data) );
+    BOOST_CHECK( compare(p->begin(), p->end()) );
+    BOOST_CHECK_EQUAL( p->header_len(), 4u );
+    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_CHECK(( p->is< GenericPacket<4,6> >() ));
+    BOOST_CHECK( !p->is<DataPacket>() );
+    BOOST_CHECK(( !p->is< GenericPacket<4,4> >() ));
+    BOOST_CHECK(( p->as< GenericPacket<4,6> >() ));
+    BOOST_CHECK( !p->as<DataPacket>() );
+
+    // check the next packet in the interpreter chain
+    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) );
+
+    // validate, that the two interpreters share the same data
+    // container
+    *p->next()->begin() = 20;
+    BOOST_CHECK( !compare(p->next()->begin(), p->next()->end(), 4) );
+    BOOST_CHECK( *p->next()->begin() == 20 );
+    BOOST_CHECK( !compare(p->begin(), p->end()) );
+    BOOST_CHECK( *(p->begin()+4) == 20 );
+
+    // 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_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> >() );
+    BOOST_REQUIRE( p->next()->next() );
+    BOOST_CHECK( p->next()->next()->is<DataPacket>() );
+    BOOST_CHECK( !p->next()->next()->next() );
+
+    BOOST_CHECK_EQUAL( p->next()->next()->size(), sizeof(data)-14 );
+    BOOST_CHECK( compare(p->next()->next()->begin(),
+                         p->next()->next()->end(), 10) );
+
+    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) );
+}
+
+BOOST_AUTO_UNIT_TEST(Packet_InsertErase)
+{
+    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_EQUAL( p->next()->next()->begin()[0], 11 );
+    BOOST_CHECK_EQUAL( p->end()[-1], 19 );
+    BOOST_CHECK_EQUAL( p->next()->end()[-1], 16 );
+    BOOST_CHECK_EQUAL( p->next()->next()->end()[-1], 16 );
+
+    p->next()->insert(p->next()->begin()+2, data, data+6);
+
+    BOOST_CHECK_EQUAL( p->size(), 26u );
+    BOOST_CHECK_EQUAL( p->next()->size(), 16u );
+    BOOST_CHECK_EQUAL( p->next()->next()->size(), 6u );
+
+    BOOST_CHECK( compare(p->begin(), p->begin()+9) );
+    BOOST_CHECK( compare(p->begin()+9, p->begin()+15) );
+    BOOST_CHECK( compare(p->begin()+15, p->end(), 9) );
+    BOOST_CHECK( compare(p->next()->begin(), p->next()->begin()+2, 7) );
+    BOOST_CHECK( compare(p->next()->begin()+2, p->next()->begin()+8) );
+    BOOST_CHECK( compare(p->next()->begin()+8, p->next()->end(), 9) );
+    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->begin(), p->end()) );
+    BOOST_CHECK( compare(p->next()->begin(), p->next()->end(), 7) );
+    BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 11) );
+
+    p->next()->insert(p->next()->begin()+4, data, data+2);
+
+    BOOST_CHECK_EQUAL( p->size(), 22u );
+    BOOST_CHECK_EQUAL( p->next()->size(), 12u );
+    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()+4, p->next()->begin()+6);
+
+    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->begin(), p->end()) );
+    BOOST_CHECK( compare(p->next()->begin(), p->next()->end(), 7) );
+    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->next()->next()->begin(), p->next()->next()->begin()+1, 11) );
+    BOOST_CHECK( compare(p->next()->next()->begin()+1, p->next()->next()->begin()+5) );
+    BOOST_CHECK( compare(p->next()->next()->begin()+5, p->end(), 12) );
+
+    p->next()->erase(p->next()->begin()+3, p->next()->begin()+9);
+
+    BOOST_CHECK_EQUAL( p->size(), 18u );
+    BOOST_CHECK_EQUAL( p->next()->size(), 8u );
+    BOOST_CHECK_EQUAL( p->next()->next()->size(), 5u );
+
+    BOOST_CHECK( compare(p->next()->next()->begin(), p->next()->next()->end(), 12) );
+    BOOST_CHECK( compare(p->begin(), p->begin()+10) );
+    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 );
+}
+
+BOOST_AUTO_UNIT_TEST(Packet_new)
+{
+    Packet::ptr p (Packet::create< GenericPacket<10,4> >());
+    BOOST_CHECK_EQUAL(p->size(), 14u);
+    Packet::ptr p2 (Packet::create< GenericPacket<2,2> >(p));
+    BOOST_CHECK_EQUAL(p2->size(),18u);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/PacketRegistry.cc b/Packets/PacketRegistry.cc
new file mode 100644 (file)
index 0000000..631d763
--- /dev/null
@@ -0,0 +1,43 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template funPacketRegistry.ons
+
+#include "PacketRegistry.hh"
+#include "PacketRegistry.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////PacketRegistry..p////////////////////////////////////////
+
+satcom::pkf::impl::PkReg_EntryImpl<satcom::pkf::DataPacket> 
+    satcom::pkf::impl::pkreg_dataEntry;
+
+///////////////////////////////PacketRegistry..e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/PacketRegistry.ct b/Packets/PacketRegistry.ct
new file mode 100644 (file)
index 0000000..e40f3ac
--- /dev/null
@@ -0,0 +1,107 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template funPacketRegistry.ons
+
+#include "PacketRegistry.ih"
+
+// Custom includes
+#include <iostream>
+#include "Utils/TypeInfo.hh"
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class KeyType>
+template <class OtherPacket>
+prefix_ void satcom::pkf::impl::PacketRegistryImpl<KeyType>::registerPacket(key_t key)
+{
+    // If this assertion fails, a Packet was registered with an already known key
+    BOOST_ASSERT( registry_.insert(std::make_pair(
+        key, Entry_ptr(new impl::PkReg_EntryImpl<OtherPacket>()))).second );
+    // If this assertion fails, the same Packet was registered with two different keys
+    BOOST_ASSERT( reverseRegistry_.insert(
+        std::make_pair(satcom::lib::typeIdValue<OtherPacket>(), key)).second );
+}
+
+template <class KeyType>
+prefix_ typename satcom::pkf::impl::PacketRegistryImpl<KeyType>::key_t
+satcom::pkf::impl::PacketRegistryImpl<KeyType>::key(satcom::lib::TypeIdValue const & type)
+{
+    typename ReversePacketMap::iterator i (reverseRegistry_.find(type));
+    if (i==reverseRegistry_.end())
+        throw PacketTypeNotRegistered();
+    return i->second;
+}
+
+template <class OtherPacket>
+prefix_ void
+satcom::pkf::impl::PkReg_EntryImpl<OtherPacket>::registerInterpreter(Packet const * p,
+                                                                     Packet::iterator b,
+                                                                     Packet::iterator e)
+{
+    p->template registerInterpreter<OtherPacket>(b,e);
+}
+
+template <class OtherPacket>
+prefix_ satcom::pkf::Packet::ptr
+satcom::pkf::impl::PkReg_EntryImpl<OtherPacket>::reinterpret(Packet * p)
+{
+    return p->template reinterpret<OtherPacket>();
+}
+
+template <class KeyType>
+prefix_ typename satcom::pkf::impl::PacketRegistryImpl<KeyType>::Entry *
+satcom::pkf::impl::PacketRegistryImpl<KeyType>::lookup(key_t key)
+{
+    typename PacketMap::iterator i (registry_.find(key));
+    if (i==registry_.end())
+        return &impl::pkreg_dataEntry;
+    return i->second.get();
+}
+
+template <class Tag>
+template <class InputIterator>
+prefix_ satcom::pkf::Packet::ptr
+satcom::pkf::PacketRegistry<Tag>::create(typename Tag::key_t key, InputIterator b,
+                                         InputIterator e)
+{
+    Packet::ptr p (Packet::create<DataPacket>(b,e));
+    return registry().lookup(key)->reinterpret(p.get());
+}
+
+template <class Tag>
+prefix_ typename satcom::pkf::PacketRegistry<Tag>::Registry &
+satcom::pkf::PacketRegistry<Tag>::registry()
+{
+    static Registry registry;
+    return registry;
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/PacketRegistry.cti b/Packets/PacketRegistry.cti
new file mode 100644 (file)
index 0000000..8c86ad8
--- /dev/null
@@ -0,0 +1,83 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template funPacketRegistry.ons
+
+#include "PacketRegistry.ih"
+
+// Custom includes
+#include "Packet.hh"
+
+#define prefix_ inline
+///////////////////////////////PacketRegistry..p///////////////////////////////////////
+
+template <class Tag>
+template <class OtherPacket>
+prefix_ void satcom::pkf::PacketRegistry<Tag>::registerPacket(typename Tag::key_t key)
+{
+    registry().registerPacket<OtherPacket>(key);
+}
+
+template <class Tag>
+template <class OtherPacket>
+prefix_ satcom::pkf::PacketRegistry<Tag>::RegistrationProxy<OtherPacket>::
+RegistrationProxy(typename Tag::key_t key)
+{
+    PacketRegistry<Tag>::template registerPacket<OtherPacket>(key);
+}
+
+template <class Tag>
+template <class OtherPacket>
+prefix_ typename Tag::key_t satcom::pkf::PacketRegistry<Tag>::key()
+{
+    return registry().key(satcom::lib::typeIdValue<OtherPacket>());
+}
+
+template <class KeyType>
+template <class OtherPacket>
+prefix_ void
+satcom::pkf::impl::PacketRegistryImpl<KeyType>::registerInterpreter(Packet * p,
+                                                                    Packet::iterator b,
+                                                                    Packet::iterator e)
+{
+    p->registerInterpreter<OtherPacket>(b,e);
+}
+
+template <class Tag, class Derived>
+prefix_ void
+satcom::pkf::PacketRegistryMixin<Tag,Derived>::registerInterpreter(typename Tag::key_t key,
+                                                                   Packet::iterator b,
+                                                                   Packet::iterator e)
+    const
+{
+    PacketRegistry<Tag>::registry().lookup(key)->registerInterpreter(
+        static_cast<Derived const * const>(this),b,e);
+}
+
+///////////////////////////////PacketRegistry..e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/PacketRegistry.hh b/Packets/PacketRegistry.hh
new file mode 100644 (file)
index 0000000..94f93b1
--- /dev/null
@@ -0,0 +1,206 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// TODO: Add parameterless create() method
+
+#ifndef HH_PacketRegistryImpl_
+#define HH_PacketRegistryImpl_ 1
+
+// Custom includes
+#include <map>
+#include <boost/utility.hpp> // for boost::noncopyable
+#include <boost/shared_ptr.hpp>
+#include "Packet.hh"
+
+//#include "PacketRegistry.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+
+    namespace impl { template <class key> class PacketRegistryImpl; }
+
+    /** \brief Packet registration facility
+
+        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 {
+              typedef some_key_type key_t;
+          };
+        \endcode
+        The key type can be an arbitrary valuetype. The PacketRegistry
+        for this Tag can then be accessed using
+        <code>PacketRegistry<SomeTag>::</code>.
+
+        The PacketRegistry class has only static members and provides
+        access to the packet registry. It allows to register Packet
+        classes and to create new Packets given a key. Methods are
+        also provided to find the key of a Packet type.
+
+        \code
+            PacketRegistry<SomeTag>::registerPacket<SomePacket>(key_of_somePacket);
+            p = PacketRegistry<SomeTag>::create(some_key,begin,end);
+            SomeTag::key_t key = PacketRegistry<SomeTag>::key<SomePacket>();
+        \endcode
+
+        Normally, packet classes are registered statically and not
+        procedurally. To this end, the RegistrationProxy is provided:
+        \code
+          PacketRegistry<SomeTag>::RegistrationProxy<SomePacket> 
+              registerSomePacket (key_of_somePacket);
+        \endcode
+        This global variable declaration will register \c SomePacket
+        with the \c SomeTag registry under the key \c
+        key_of_somePacket. The variable \c registerSomePacket is a
+        dummy. It's only function is to force the call of it's
+        constructor during global construction time.
+
+        The PacketRegistry's purpose is mostly to assist in
+        implementing the \v v_nextInterpreter() member of packet
+        facades. This is further supported by the PacketRegistryMixin
+        class.
+     */
+    template <class Tag>
+    class PacketRegistry
+    {
+    public:
+        // TODO: This fails to work within a library since the linker will
+        // remove all unused object files ...
+        /** \brief Statically register a packet type in a PacketRegistry
+         */
+        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.
+
+            \par Preconditions:
+                The given \c key must be unique and not be assigned to
+                any other packet class in this registry.
+                The Packet must not already be registered in the registry.
+
+            \param OtherPacket packet to regiser
+            \param key key of the packet
+         */
+        template <class OtherPacket>
+        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
+
+            \param OtherPacket packet of which the key is requested
+            \returns key of the packet
+            \throws PacketTypeNotRegistered if the packet type is not
+                found in the registry.
+         */
+        template <class OtherPacket>
+        static typename Tag::key_t key();
+
+        /** \brief Create new Packet
+
+            \param key Key of packet type to create instance of
+            \param b begin iterator argument to Packet::create()
+            \param e end iterator argment to Packet::create()
+            \returns new Instance of the packet type registered under
+                key or DataPacket, if the key is not registered.
+         */
+        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;
+    };
+
+    /** \brief Helper class for v_nextInterpreter implementations
+
+        This class is a helper class which is to be inherited from in
+        a packet facade which wants to register a new interpreter with
+        the packet framework depending on a packet registry.
+
+        This mixin class provides a new registerInterpreter
+        implementation which can be used besides the methods provided
+        bei satcom::pkf::Packet to add a new interpreter to the
+        interpreter chain.
+
+        \code
+          class SomePacket
+              : public Packet,
+                private PacketRegistryMixin<SomeTag,SomePacket>
+          {
+              using Packet::retgisterInterpreter;
+              using PacketRegistryMixin<SomeTag,SomePacket>::registerInterpreter;
+
+              virtual void v_nextInterpreter()
+              {
+                  registerInterpreter(some_key_value, subpacket_begin, subpacket_end);
+              }
+          };
+        \endcode
+        This example is not complete, it only contains the parts
+        concerned with PacketRegistryMixin.
+     */
+    template <class Tag, class Derived>
+    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, 
+                                 Packet::iterator b, Packet::iterator e) const;
+    };
+
+    struct PacketTypeNotRegistered : public std::exception
+    { virtual char const * what() const throw() { return "packet type not registered"; } };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "PacketRegistry.cci"
+#include "PacketRegistry.ct"
+#include "PacketRegistry.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/PacketRegistry.ih b/Packets/PacketRegistry.ih
new file mode 100644 (file)
index 0000000..2a752b2
--- /dev/null
@@ -0,0 +1,108 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_PacketRegistryImpl_
+#define IH_PacketRegistryImpl_ 1
+
+// Custom includes
+#include "Packet.hh"
+#include "DataPacket.hh"
+#include "typeidvalue.hh"
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+namespace impl {
+
+    struct PkReg_Entry {
+        virtual void registerInterpreter(Packet const * p, 
+                                         Packet::iterator b, Packet::iterator e) = 0;
+        virtual Packet::ptr reinterpret(Packet * p) = 0;
+    };
+
+    template <class OtherPacket>
+    struct PkReg_EntryImpl
+        : public PkReg_Entry
+    {
+        virtual void registerInterpreter(Packet const * p, Packet::iterator b, Packet::iterator e);
+        virtual Packet::ptr reinterpret(Packet * p);
+    };
+
+
+    template <class KeyType>
+    class PacketRegistryImpl : private boost::noncopyable
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+        
+        typedef KeyType key_t;
+
+        typedef impl::PkReg_Entry Entry;
+        
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        // default default constructor
+        // no copy constructor
+        // no copy assignment
+        // default destructor
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        template <class OtherPacket>
+        void registerPacket(key_t key);
+
+        key_t key(satcom::lib::TypeIdValue const & type);
+
+        Entry * lookup(key_t key);
+
+    protected:
+
+    private:
+        template <class OtherPacket>
+        static void registerInterpreter(Packet * p, Packet::iterator b, Packet::iterator e);
+
+        typedef boost::shared_ptr<Entry> Entry_ptr;
+        typedef std::map<key_t, Entry_ptr> PacketMap;
+        typedef std::map<satcom::lib::TypeIdValue, key_t> ReversePacketMap;
+
+        PacketMap registry_;
+        ReversePacketMap reverseRegistry_;
+    };
+
+    extern PkReg_EntryImpl<DataPacket> pkreg_dataEntry;
+
+}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/PacketRegistry.test.cc b/Packets/PacketRegistry.test.cc
new file mode 100644 (file)
index 0000000..4d235c7
--- /dev/null
@@ -0,0 +1,171 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "PacketRegistry.test.hh"
+//#include "PacketRegistry.test.ih"
+
+// Custom includes
+#include <string>
+#include "PacketRegistry.hh"
+#include "DataPacket.hh"
+#include "ParseInt.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+
+    using namespace satcom::pkf;
+
+    struct BaseTag {
+        typedef unsigned key_t;
+    };
+
+    struct StringTag {
+        typedef std::string key_t;
+    };
+
+    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) {}
+
+        virtual void v_nextInterpreter() const
+            { registerInterpreter(type(), begin()+2, end()); }
+        virtual void v_finalize() {}
+        virtual void v_dump(std::ostream & os) const {}
+
+        friend class Packet;
+    };
+
+    class FooPacket : public Packet
+    {
+    public:
+        typedef ptr_t<FooPacket>::ptr ptr;
+        typedef iterator byte_iterator;
+        
+        static bool check(iterator b, iterator e) { return true; }
+
+    private:
+        template <class Arg>
+        FooPacket(Arg const & arg) : Packet(arg) {}
+
+        virtual void v_nextInterpreter() const {}
+        virtual void v_finalize() {}
+        virtual void v_dump(std::ostream & os) const {}
+
+        friend class Packet;
+    };
+
+    class BarPacket : public Packet
+    {
+    public:
+        typedef ptr_t<BarPacket>::ptr ptr;
+        typedef iterator byte_iterator;
+        
+        static bool check(iterator b, iterator e) { return true; }
+
+    private:
+        template <class Arg>
+        BarPacket(Arg const & arg) : Packet(arg) {}
+
+        virtual void v_nextInterpreter() const {}
+        virtual void v_finalize() {}
+        virtual void v_dump(std::ostream & os) const {}
+
+        friend class Packet;
+    };
+
+    namespace reg {
+        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>() );
+    }
+
+    PacketRegistry<BaseTag>::registerPacket<FooPacket>(1u);
+    PacketRegistry<BaseTag>::registerPacket<BarPacket>(2u);
+
+    BOOST_CHECK_EQUAL( PacketRegistry<BaseTag>::key<FooPacket>(), 1u );
+    BOOST_CHECK_EQUAL( PacketRegistry<BaseTag>::key<BarPacket>(), 2u );
+    BOOST_CHECK_THROW( PacketRegistry<BaseTag>::key<DataPacket>(), PacketTypeNotRegistered );
+
+    {
+        BasePacket::ptr p (Packet::create<BasePacket>(data, data+sizeof(data)));
+        BOOST_CHECK( p->next()->is<FooPacket>() );
+    }
+
+    data[1] = 0x02;
+
+    {
+        BasePacket::ptr p (Packet::create<BasePacket>(data, data+sizeof(data)));
+        BOOST_CHECK( p->next()->is<BarPacket>() );
+    }
+    
+    data[0] = 0x01;
+
+    {
+        BasePacket::ptr p (Packet::create<BasePacket>(data, data+sizeof(data)));
+        BOOST_CHECK( p->next()->is<DataPacket>() );
+    }
+
+    BOOST_CHECK_EQUAL( PacketRegistry<StringTag>::key<FooPacket>(), "foo" );
+    BOOST_CHECK( PacketRegistry<StringTag>::create("foo",data,data+sizeof(data))
+                 ->is<FooPacket>() );
+
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseArray.cti b/Packets/ParseArray.cti
new file mode 100644 (file)
index 0000000..c932dd8
--- /dev/null
@@ -0,0 +1,206 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+#include "ParseArray.ih"
+
+// Custom includes
+#include <algorithm>
+#if defined(_STLP_ALGORITHM) || (__GNUC__<4 && __GNUC_MINOR__<4)
+#define copy_n std::copy_n
+#else
+#include <ext/algorithm>
+#define copy_n __gnu_cxx::copy_n
+#endif
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::Parse_Array()
+{}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::Parse_Array(Iterator const & i)
+    : ParserBase<Iterator,IPacket>(i) 
+{}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ unsigned satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::bytes()
+{
+    return elements*Parser::bytes();
+}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ bool
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::check(Iterator const & e)
+    const
+{
+    return e-this->i() >= bytes();
+}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ void satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::init()
+    const
+{
+    iterator e=end();
+    for (iterator i=begin(); i!=e; ++i) i->init();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::size_type
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::size()
+{
+    return elements;
+}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::iterator
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::begin()
+    const
+{
+    return iterator(this->i());
+}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::iterator
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::end()
+    const
+{
+    return iterator(this->i()+bytes());
+}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::range_type
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::range()
+    const
+{
+    return std::make_pair(begin(),end());
+}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::iterator
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::value()
+    const
+{
+    return begin();
+}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::value_type
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::operator[](difference_type i)
+    const
+{
+    return begin()[i];
+}
+
+template <unsigned elements, class Parser, class Iterator, class IPacket>
+template <class InputIterator>
+prefix_ satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket> const &
+satcom::pkf::Parse_Array<elements,Parser,Iterator,IPacket>::operator=(InputIterator const & i)
+{
+    copy_n(i,size(),begin());
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+template <class Parser, class Iterator>
+prefix_ Iterator satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::raw()
+    const
+{
+    return i_;
+}
+
+template <class Parser, class Iterator>
+prefix_ Parser satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::operator[](int i)
+    const
+{
+    return (*this+i).dereference();
+}
+
+template <class Parser, class Iterator>
+prefix_ satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::Parse_Array_iterator()
+    : i_()
+{}
+
+template <class Parser, class Iterator>
+prefix_  satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::
+Parse_Array_iterator(Iterator const & i)
+    : i_(i)
+{}
+
+template <class Parser, class Iterator>
+prefix_ Parser
+satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::dereference()
+    const
+{
+    return Parser(i_);
+}
+
+template <class Parser, class Iterator>
+prefix_ bool satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::
+equal(Parse_Array_iterator const & other)
+    const
+{
+    return i_==other.i_;
+}
+
+template <class Parser, class Iterator>
+prefix_ int satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::
+distance_to(Parse_Array_iterator const & other)
+    const
+{
+    return (other.i_-i_)/Parser::bytes();
+}
+
+template <class Parser, class Iterator>
+prefix_ void satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::increment()
+{
+    i_ += Parser::bytes();
+}
+
+template <class Parser, class Iterator>
+prefix_ void satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::decrement()
+{
+    i_ -= Parser::bytes();
+}
+
+template <class Parser, class Iterator>
+prefix_ void
+satcom::pkf::impl::Parse_Array_iterator<Parser,Iterator>::advance(int n)
+{
+    i_ += n*Parser::bytes();
+}
+
+#undef copy_n
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseArray.hh b/Packets/ParseArray.hh
new file mode 100644 (file)
index 0000000..f4a0d41
--- /dev/null
@@ -0,0 +1,91 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_ParseArray_
+#define HH_ParseArray_ 1
+
+// Custom includes
+#include <utility> // for std::pair
+#include "ParserBase.hh"
+
+//#include "ParseArray.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+    
+    namespace impl { template <class,class> class Parse_Array_iterator; }
+
+    /* Parse_Array has the external interface of a container class
+     */
+    template <unsigned elements, class Parser, class Iterator=nil, class IPacket=nil>
+    struct Parse_Array : public ParserBase<Iterator,IPacket>
+    {
+        ///////////////////////////////////////////////////////////////////////////
+        // Parser interface
+
+        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;
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Container interface
+
+        typedef typename Parser::template rebind<Iterator>::parser value_type;
+        typedef impl::Parse_Array_iterator<value_type,Iterator> iterator;
+        typedef unsigned size_type;
+        typedef int difference_type;
+        typedef std::pair<iterator,iterator> range_type;
+
+        static size_type size();
+
+        iterator begin() const;
+        iterator end() const;
+        range_type range() const;
+        iterator value() const;
+
+        value_type operator[](difference_type i) const;
+
+        template <class InputIterator>
+        Parse_Array const & operator= (InputIterator const & i);
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ParseArray.cci"
+//#include "ParseArray.ct"
+#include "ParseArray.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseArray.ih b/Packets/ParseArray.ih
new file mode 100644 (file)
index 0000000..85e850f
--- /dev/null
@@ -0,0 +1,69 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_ParseArray_
+#define IH_ParseArray_ 1
+
+// Custom includes
+#include <boost/iterator/iterator_facade.hpp>
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+template <class Parser, class Iterator>
+class satcom::pkf::impl::Parse_Array_iterator
+    : public boost::iterator_facade< Parse_Array_iterator<Parser,Iterator>,
+                                     Parser,
+                                     boost::random_access_traversal_tag,
+                                     Parser >
+{
+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++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseArray.test.cc b/Packets/ParseArray.test.cc
new file mode 100644 (file)
index 0000000..59a9898
--- /dev/null
@@ -0,0 +1,67 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ParseArray.test.hh"
+//#include "ParseArray.test.ih"
+
+// Custom includes
+#include "ParseArray.hh"
+#include "ParseInt.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+BOOST_AUTO_UNIT_TEST(parseArray_test)
+{
+    unsigned char data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+    typedef unsigned char * iterator;
+    typedef Parse_Array<6,Parse_UInt8<>,iterator> Parse_UInt8Array6;
+    Parse_UInt8Array6 v (data);
+    BOOST_CHECK_EQUAL( v[0], 0x00 );
+    BOOST_CHECK_EQUAL( v[5], 0x05 );
+    BOOST_CHECK_EQUAL( *v.begin(), 0x00 );
+    Parse_UInt8Array6::iterator i1 (v.begin());
+    Parse_UInt8Array6::iterator i2 (v.begin());
+    ++i1;
+    BOOST_CHECK_EQUAL( *i1, 0x01 );
+    BOOST_CHECK_EQUAL( i1[-1], 0x00 );
+    BOOST_CHECK_EQUAL( i1-i2, 1 );
+    BOOST_CHECK_EQUAL( i2-i1, -1 );
+    --i1;
+    BOOST_CHECK( i1==i2 );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseInt.hh b/Packets/ParseInt.hh
new file mode 100644 (file)
index 0000000..1207eaf
--- /dev/null
@@ -0,0 +1,320 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_ParseInt_
+#define HH_ParseInt_ 1
+
+// Custom includes
+#include "ParserBase.hh"
+#include <boost/cstdint.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/integer/integer_mask.hpp>
+
+//#include "ParseInt.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+#include "ParseInt.ih"
+
+namespace satcom {
+namespace pkf {
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_Int8
+       : 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;
+
+        static unsigned bytes() { return 1; }
+
+        Parse_Int8() {}
+        explicit Parse_Int8(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::int8_t value_type;
+
+        value_type value() const { return this->i()[0]; }
+        void value(value_type v) { this->i()[0] = v; }
+        Parse_Int8 const & operator= (value_type other) { value(other); return *this; }
+    };
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_UInt8
+       : public impl::ParseIntOps<Parse_UInt8<Iterator,IPacket>,boost::uint8_t>,
+          public ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_UInt8<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return 1; }
+        
+        Parse_UInt8() {}
+        explicit Parse_UInt8(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::uint8_t value_type;
+
+        value_type value() const { return this->i()[0]; }
+        void value(value_type v) { this->i()[0] = v; }
+        Parse_UInt8 const & operator= (value_type other) { value(other); return *this; }
+    };
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_Int16
+       : public impl::ParseIntOps<Parse_Int16<Iterator,IPacket>,boost::int16_t>,
+          public ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_Int16<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return 2; }
+
+        Parse_Int16() {}
+        explicit Parse_Int16(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::int16_t value_type;
+
+        value_type value() const { return impl::parse_uint16(this->i()); }
+        void value(value_type v) { impl::write_uint16(this->i(),v); }
+        Parse_Int16 const & operator= (value_type other) { value(other); return *this; }
+    };
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_UInt16
+       : public impl::ParseIntOps<Parse_UInt16<Iterator,IPacket>,boost::uint16_t>,
+          public ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_UInt16<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return 2; }
+
+        Parse_UInt16() {}
+        explicit Parse_UInt16(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::uint16_t value_type;
+
+        value_type value() const { return impl::parse_uint16(this->i()); }
+        void value(value_type v) { impl::write_uint16(this->i(),v); }
+        Parse_UInt16 const & operator= (value_type other) { value(other); return *this; }
+    };
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_Int24
+       : public impl::ParseIntOps<Parse_Int24<Iterator,IPacket>,boost::int32_t>,
+          public ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_Int24<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return 3; }
+
+        Parse_Int24() {}
+        explicit Parse_Int24(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::int32_t value_type;
+
+        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 ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_UInt24<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return 3; }
+
+        Parse_UInt24() {}
+        explicit Parse_UInt24(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::uint32_t value_type;
+
+        value_type value() const { return impl::parse_uint24(this->i()); }
+        void value(value_type v) { impl::write_uint24(this->i(),v); }
+        Parse_UInt24 const & operator= (value_type other) { value(other); return *this; }
+    };
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_Int32
+       : public impl::ParseIntOps<Parse_Int32<Iterator,IPacket>,boost::int32_t>,
+          public ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_Int32<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return 4; }
+
+        Parse_Int32() {}
+        explicit Parse_Int32(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::int32_t value_type;
+
+        value_type value() const { return impl::parse_uint32(this->i()); }
+        void value(value_type v) { impl::write_uint32(this->i(),v); }
+        Parse_Int32 const & operator= (value_type other) { value(other); return *this; }
+    };
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_UInt32
+       : public impl::ParseIntOps<Parse_UInt32<Iterator,IPacket>,boost::uint32_t>,
+          public ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_UInt32<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return 4; }
+
+        Parse_UInt32() {}
+        explicit Parse_UInt32(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::uint32_t value_type;
+
+        value_type value() const { return impl::parse_uint32(this->i()); }
+        void value(value_type v) { impl::write_uint32(this->i(),v); }
+        Parse_UInt32 const & operator= (value_type other) { value(other); return *this; }
+    };
+
+    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 ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_IntField<start,end,I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return (end-1)/8+1; }
+
+        Parse_IntField() {}
+        explicit Parse_IntField(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::int32_t value_type;
+
+        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;
+        }
+        void value(value_type v) { impl::parse_bitfield<Iterator,start,end>::write(this->i(),v); }
+        Parse_IntField const & operator= (value_type other) { value(other); return *this; }
+
+    private:
+        BOOST_STATIC_ASSERT( start<end );
+        BOOST_STATIC_ASSERT( end-start<=32 );
+    };
+
+    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 ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_UIntField<start,end,I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return (end-1)/8+1; }
+
+        Parse_UIntField() {}
+        explicit Parse_UIntField(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef boost::uint32_t value_type;
+
+        value_type value() const { return impl::parse_bitfield<Iterator,start,end>::parse(this->i()); }
+        void value(value_type v) { impl::parse_bitfield<Iterator,start,end>::write(this->i(),v); }
+        Parse_UIntField const & operator= (value_type other) { value(other); return *this; }
+
+    private:
+        BOOST_STATIC_ASSERT( start<end );
+        BOOST_STATIC_ASSERT( end-start<=32 );
+    };
+
+    template <unsigned bit, class Iterator=nil, class IPacket=nil>
+    struct Parse_Flag
+       : public impl::ParseIntOps<Parse_Flag<bit,Iterator,IPacket>,bool>,
+          public ParserBase<Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_Flag<bit,I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        static unsigned bytes() { return 1; }
+
+        Parse_Flag() {}
+        explicit Parse_Flag(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef bool value_type;
+
+        value_type value() const { return this->i()[bit/8] & (1<<(7-(bit%8))); }
+        void value(value_type v) { 
+            if (v) this->i()[0] |= 1<<(7-(bit%8));
+            else   this->i()[0] &= ~(1<<(7-(bit%8)));
+        }
+        Parse_Flag const & operator= (value_type other) { value(other); return *this; }
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ParseInt.cci"
+//#include "ParseInt.ct"
+//#include "ParseInt.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseInt.ih b/Packets/ParseInt.ih
new file mode 100644 (file)
index 0000000..70c5859
--- /dev/null
@@ -0,0 +1,219 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_ParseInt_
+#define IH_ParseInt_ 1
+
+// Custom includes
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+namespace impl {
+    
+    ///////////////////////////////////////////////////////////////////////////
+    // Integer operators
+
+    template <class Derived, class Value>
+    class ParseIntOps
+    {
+    public:
+        typedef Value value_type;
+
+        operator Value () const { return derived().value(); }
+
+#       define unary(op) \
+           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(); }
+
+        unary(~)
+        unary(!)
+        unary(-)
+
+        mutator(+)
+        mutator(-)
+        mutator(*)
+        mutator(/)
+        mutator(%)
+        mutator(<<)
+        mutator(>>)
+        mutator(&)
+        mutator(|)
+        mutator(^)
+
+#       undef unary
+#       undef mutator
+            
+        Derived const & operator ++ ()
+            { derived().value( derived.value()+1 ); return derived(); }
+        Derived const & operator -- ()
+            { derived().value( derived.value()-1 ); return derived(); }
+
+    private:
+        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)
+    {
+        return i[1] | i[0]<<8;
+    }
+
+    template <class Iterator>
+    void write_uint16(Iterator const & i, boost::uint16_t v)
+    {
+        i[0] = ( v >>  8 ) & 0xff;
+        i[1] = ( v       ) & 0xff;
+    }
+
+    template <class Iterator>
+    boost::uint32_t parse_uint24(Iterator const & i)
+    {
+        return i[2] | i[1]<<8 | i[0]<<16;
+    }
+
+    template <class Iterator>
+    void write_uint24(Iterator const & i, boost::uint32_t v)
+    {
+        i[0] = ( v >> 16 ) & 0xff;
+        i[1] = ( v >>  8 ) & 0xff;
+        i[2] = ( v       ) & 0xff;
+    }
+
+    template <class Iterator>
+    boost::uint32_t parse_uint32(Iterator const & i)
+    {
+        return i[3] | i[2]<<8 | i[1]<<16 | i[0]<<24;
+    }
+
+    template <class Iterator>
+    void write_uint32(Iterator const & i, boost::uint32_t v)
+    {
+        i[0] = ( v >> 24 ) & 0xff;
+        i[1] = ( v >> 16 ) & 0xff;
+        i[2] = ( v >>  8 ) & 0xff;
+        i[3] = ( v       ) & 0xff;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // bitfield extraction
+
+    template <class Iterator, unsigned offset, unsigned endb, unsigned start, unsigned end>
+    struct parse_bitfield_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 ) 
+                     | (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, 
+                         (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))
+                | ((v>>(end-8)) & boost::low_bits_mask_t<8-start>::sig_bits);
+        }
+    };
+
+    template <class Iterator, unsigned offset, unsigned start, unsigned end>
+    struct parse_bitfield_i<Iterator, offset, 3, start, end>
+    {
+        static boost::uint32_t parse(Iterator const & i) {
+            return ( parse_uint32(i+offset)>>(32-end) )
+                & boost::low_bits_mask_t<end-start>::sig_bits;
+        }
+
+        static void write(Iterator const & i, boost::uint32_t v) {
+            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)));
+        }
+    };
+
+    template <class Iterator, unsigned offset, unsigned start, unsigned end>
+    struct parse_bitfield_i<Iterator, offset, 2, start, end>
+    {
+        static boost::uint32_t parse(Iterator const & i) {
+            return ( parse_uint24(i+offset)>>(24-end) )
+                & boost::low_bits_mask_t<end-start>::sig_bits;
+        }
+
+        static void write(Iterator const & i, boost::uint32_t v) {
+            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)));
+        }
+    };
+
+    template <class Iterator, unsigned offset, unsigned start, unsigned end>
+    struct parse_bitfield_i<Iterator, offset, 1, start, end>
+    {
+        static boost::uint32_t parse(Iterator const & i) {
+            return ( parse_uint16(i+offset)>>(16-end) )
+                & boost::low_bits_mask_t<end-start>::sig_bits;
+        }
+
+        static void write(Iterator const & i, boost::uint32_t v) {
+            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)));
+        }
+    };
+
+    template <class Iterator, unsigned offset, unsigned start, unsigned end>
+    struct parse_bitfield_i<Iterator, offset, 0, start, end>
+    {
+        static boost::uint32_t parse(Iterator const & i) {
+            return ( i[offset]>>(8-end) ) 
+                & boost::low_bits_mask_t<end-start>::sig_bits;
+        }
+
+        static void write(Iterator const & i, boost::uint32_t v) {
+            i[offset] = (i[offset] & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(8-end)))
+                | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (8-end));
+        }
+    };
+
+    template <class Iterator, unsigned start, unsigned end>
+    struct parse_bitfield 
+        : public parse_bitfield_i<Iterator,start/8,(end-1)/8-start/8,start%8,end-8*(start/8)>
+    {};
+
+}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseInt.test.cc b/Packets/ParseInt.test.cc
new file mode 100644 (file)
index 0000000..7325359
--- /dev/null
@@ -0,0 +1,241 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ParseInt.test.hh"
+//#include "ParseInt.test.ih"
+
+// Custom includes
+#include "ParseInt.hh"
+#include "Packet.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+BOOST_AUTO_UNIT_TEST(parseInt_fixedSizes)
+{
+    unsigned char data[] = { 0x8e, 0x2f, 0x57, 0x12, 0xd1 };
+    typedef unsigned char * iterator;
+
+    BOOST_CHECK_EQUAL(Parse_Int8<iterator>(data).value(), -114);
+    BOOST_CHECK_EQUAL(Parse_Int8<iterator>(data+1).value(), 47);
+    BOOST_CHECK_EQUAL(Parse_UInt8<iterator>(data).value(), 142u);
+
+    BOOST_CHECK_EQUAL(Parse_Int16<iterator>(data).value(), -29137);
+    BOOST_CHECK_EQUAL(Parse_Int16<iterator>(data+1).value(), 12119);
+    BOOST_CHECK_EQUAL(Parse_UInt16<iterator>(data).value(), 36399u);
+
+    BOOST_CHECK_EQUAL(Parse_Int24<iterator>(data).value(), -7458985);
+    BOOST_CHECK_EQUAL(Parse_Int24<iterator>(data+1).value(), 3102482);
+    BOOST_CHECK_EQUAL(Parse_UInt24<iterator>(data).value(), 9318231u);
+
+    BOOST_CHECK_EQUAL(Parse_Int32<iterator>(data).value(), -1909500142);
+    BOOST_CHECK_EQUAL(Parse_Int32<iterator>(data+1).value(), 794235601);
+    BOOST_CHECK_EQUAL(Parse_UInt32<iterator>(data).value(), 2385467154u);
+}
+
+BOOST_AUTO_UNIT_TEST(parseInt_bits)
+{
+    //                       0         1         2         3         4
+    //                       012345678901234567890123456789012345678901234567
+    //                       --------        --------        --------
+    //                       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);
+    BOOST_CHECK_EQUAL((Parse_UIntField<3,7,iterator>(data).value()), 1u);
+    BOOST_CHECK_EQUAL((Parse_IntField<3,7,iterator>(data).value()), 1);
+    BOOST_CHECK_EQUAL((Parse_UIntField<0,8,iterator>(data).value()), 99u);
+
+    // 2 byte
+    BOOST_CHECK_EQUAL((Parse_UIntField<5,12,iterator>(data).value()), 61u);
+    BOOST_CHECK_EQUAL((Parse_UIntField<0,12,iterator>(data).value()), 1597u);
+    BOOST_CHECK_EQUAL((Parse_UIntField<8,13,iterator>(data).value()), 26u);
+    BOOST_CHECK_EQUAL((Parse_UIntField<8,16,iterator>(data).value()), 215u);
+    BOOST_CHECK_EQUAL((Parse_UIntField<0,16,iterator>(data).value()), 25559u);
+
+    // 3 byte
+    BOOST_CHECK_EQUAL((Parse_UIntField<6,20,iterator>(data).value()), 15733u);
+    BOOST_CHECK_EQUAL((Parse_IntField<6,20,iterator>(data).value()), -651);
+    BOOST_CHECK_EQUAL((Parse_UIntField<13,22,iterator>(data).value()), 470u);
+
+    // 4 byte
+    BOOST_CHECK_EQUAL((Parse_UIntField<3,28,iterator>(data).value()), 4027811u);
+    BOOST_CHECK_EQUAL((Parse_UIntField<13,38,iterator>(data).value()), 30837865u);
+    BOOST_CHECK_EQUAL((Parse_UIntField<8,40,iterator>(data).value()), 3613012388u);
+    BOOST_CHECK_EQUAL((Parse_IntField<8,40,iterator>(data).value()), -681954908);
+
+    // 5 byte
+    BOOST_CHECK_EQUAL((Parse_UIntField<3,34,iterator>(data).value()), 257779910u);
+    BOOST_CHECK_EQUAL((Parse_IntField<13,41,iterator>(data).value()), -21732536);
+
+    // single bit
+    BOOST_CHECK_EQUAL((Parse_Flag<32,iterator>(data).value()), true);
+    BOOST_CHECK_EQUAL((Parse_Flag<12,iterator>(data).value()), false);
+}
+
+BOOST_AUTO_UNIT_TEST(parseInt_assign)
+{
+    unsigned char data[] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
+    typedef unsigned char * iterator;
+
+    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 );
+
+    Parse_Int24<iterator>(data).value(0x234567);
+    BOOST_CHECK_EQUAL( data[0], 0x23 );
+    BOOST_CHECK_EQUAL( data[1], 0x45 );
+    BOOST_CHECK_EQUAL( data[2], 0x67 );
+
+    Parse_Int32<iterator>(data).value(0xfedcba98);
+    BOOST_CHECK_EQUAL( data[0], 0xfe );
+    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 );
+
+    Parse_IntField<6,9,iterator>(data).value(0x2);
+    BOOST_CHECK_EQUAL( data[0], 0xcd );
+    BOOST_CHECK_EQUAL( data[1], 0x5c );
+    BOOST_CHECK_EQUAL( data[2], 0xba );
+
+    Parse_IntField<2,21,iterator>(data).value(0x13d75);
+    BOOST_CHECK_EQUAL( data[0], 0xc9 );
+    BOOST_CHECK_EQUAL( data[1], 0xeb );
+    BOOST_CHECK_EQUAL( data[2], 0xaa );
+    BOOST_CHECK_EQUAL( data[3], 0x98 );
+
+    Parse_UIntField<4,34,iterator>(data).value(0x268ad497u);
+    BOOST_CHECK_EQUAL( (Parse_UIntField<4,34,iterator>(data).value()), 0x268ad497u );
+}
+
+BOOST_AUTO_UNIT_TEST(parseInt_operators) 
+{
+    unsigned char data[] = { 0x63, 0xd7, 0x5a, 0x31, 0xa4, 0x46 };
+
+    Parse_UInt24<unsigned char *> p1(data);
+    Parse_UInt16<unsigned char *> p2(data+3);
+
+    BOOST_CHECK_EQUAL( ~p1, 4288424101u );
+    BOOST_CHECK ( !!p1 );
+    BOOST_CHECK_EQUAL( -p1, -6543194u );
+
+    p1 += 0x10;
+    BOOST_CHECK_EQUAL( p1, 6543210u );
+    p1 -= 0x10;
+    BOOST_CHECK_EQUAL( p1, 6543194u );
+
+    p1 += p2;
+    BOOST_CHECK_EQUAL( p1, 6555902u );
+    p2 += p1;
+    // Here some idiotic automatic promotion from unsigned short ->
+    // int happens in the second macro parameter ... hrmpf ...
+    BOOST_CHECK_EQUAL( p2, 15010 );
+
+    p1 = 0x123456u;
+    BOOST_CHECK_EQUAL( data[0], 0x12 );
+    BOOST_CHECK_EQUAL( data[1], 0x34 );
+    BOOST_CHECK_EQUAL( data[2], 0x56 );
+    BOOST_CHECK_EQUAL( data[3], 0x3a );
+
+    // I stop here ... this is absolutely identical for all other
+    // operators and all other integer types. If really some error pops
+    // up, I'll add a check here ...
+}
+
+namespace {
+    
+    template < class P >
+    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) 
+            : Packet(arg) {}
+
+        virtual void v_nextInterpreter() const {}
+       virtual void v_finalize() {}
+        virtual void v_dump(std::ostream &) const {}
+
+        friend class Packet;
+    };
+
+    template < class P >
+    typename P::value_type packetCheck()
+    {
+        unsigned char data[] = { 0x8e, 0x2f, 0x57, 0x12, 0xd1 };
+        typename TestPacket<P>::ptr p (Packet::create< TestPacket<P> >(data, data+sizeof(data)));
+        return p->value();
+    }
+
+}
+
+BOOST_AUTO_UNIT_TEST(parseInt_inherited)
+{
+    BOOST_CHECK_EQUAL(packetCheck< Parse_Int8<> >(), -114);
+    BOOST_CHECK_EQUAL(packetCheck< Parse_UInt8<> >(), 142u);
+
+    BOOST_CHECK_EQUAL(packetCheck< Parse_Int16<> >(), -29137);
+    BOOST_CHECK_EQUAL(packetCheck< Parse_UInt16<> >(), 36399u);
+
+    BOOST_CHECK_EQUAL(packetCheck< Parse_Int24<> >(), -7458985);
+    BOOST_CHECK_EQUAL(packetCheck< Parse_UInt24<> >(), 9318231u);
+
+    BOOST_CHECK_EQUAL(packetCheck< Parse_Int32<> >(), -1909500142);
+    BOOST_CHECK_EQUAL(packetCheck< Parse_UInt32<> >(), 2385467154u);
+
+    BOOST_CHECK_EQUAL((packetCheck< Parse_IntField<3,28> >()), 14873969);
+    BOOST_CHECK_EQUAL((packetCheck< Parse_UIntField<3,28> >()), 14873969u);
+    BOOST_CHECK_EQUAL((packetCheck< Parse_Flag<11> >()), false);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseListS.ct b/Packets/ParseListS.ct
new file mode 100644 (file)
index 0000000..7e65fa9
--- /dev/null
@@ -0,0 +1,121 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+#include "ParseListS.ih"
+
+// Custom includes
+#include <algorithm>
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ unsigned satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::bytes()
+    const
+{
+    iterator i (begin());
+    iterator e (end());
+    size_type s (0);
+    for (; i!=e; ++i)
+        s += i->bytes();
+    // The sentinel is not part of the range
+    // but it's part of the list !!
+    return s+i->bytes();
+}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ bool
+satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::check(Iterator const & e)
+    const
+{
+    byte_iterator i (this->i());
+    for (;;) {
+        value_type v (i);
+        if (!v.check(e)) return false;
+        if (sentinel::check(v)) return true;
+        size_type s (v.bytes());
+        if (s==0) return false;
+        i += s;
+    }
+}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ void satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::init()
+    const
+{
+    iterator i (begin());
+    iterator e (end());
+    for (;i!=e; ++i)
+        i->init();
+    // The sentinel is not part of the range
+    // but it's part of the list !!
+    i->init();
+}
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>
+
+template <class Parser, class Sentinel, class Container>
+template <class Value>
+prefix_ void
+satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::insert(iterator pos,
+                                                                    Value const & t)
+{
+    // FIXME: What, if pos == end() / default constructed iterator ?
+    size_type ix (pos.raw()-container_.begin());
+    container_.insert(pos.raw(),t.bytes(),0);
+    Parser(container_.begin()+ix).value(t);
+}
+
+template <class Parser, class Sentinel, class Container>
+template <class Value>
+prefix_ void
+satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::insert(iterator pos, size_type n,
+                                                                    Value const & t)
+{
+    size_type ix (pos.raw()-container_.begin());
+    container_.insert(pos.raw(),n*t.bytes(),0);
+    typename Container::iterator i (container_.begin()+ix);
+    for (; n; ++i, --n)
+        Parser(i).value(t);
+}
+
+template <class Parser, class Sentinel, class Container>
+template <class InputIterator>
+prefix_ void
+satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::insert(iterator pos,
+                                                                    InputIterator f,
+                                                                    InputIterator l)
+{
+    for (;f!=l;++f,++pos) insert(pos,*f);
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseListS.cti b/Packets/ParseListS.cti
new file mode 100644 (file)
index 0000000..db91757
--- /dev/null
@@ -0,0 +1,201 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+#include "ParseListS.ih"
+
+// Custom includes
+#include <boost/assert.hpp>
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::Parse_ListS()
+{}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_
+satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::Parse_ListS(Iterator const & i)
+    : ParserBase<Iterator,IPacket>(i)
+{}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::size_type
+satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::size()
+    const
+{
+    return std::distance(begin(),end());
+}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ bool satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::empty()
+    const
+{
+    return begin()==end();
+}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::iterator
+satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::begin()
+    const
+{
+    return iterator(this->i());
+}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::iterator
+satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::end()
+    const
+{
+    return iterator();
+}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::range_type
+satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::range()
+    const
+{
+    return std::make_pair(begin(),end());
+}
+
+template <class Parser, class Sentinel, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::range_type
+satcom::pkf::Parse_ListS<Parser,Sentinel,Iterator,IPacket>::value()
+    const
+{
+    return range();
+}
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::pkf::impl::Parse_ListS_iterator<Parser,Sentinel,Iterator>
+
+template <class Parser, class Sentinel, class Iterator>
+prefix_
+satcom::pkf::impl::Parse_ListS_iterator<Parser,Sentinel,Iterator>::Parse_ListS_iterator()
+    : i_(), atEnd_(true)
+{}
+
+template <class Parser, class Sentinel, class Iterator>
+prefix_ 
+satcom::pkf::impl::Parse_ListS_iterator<Parser,Sentinel,Iterator>::
+Parse_ListS_iterator(Iterator const & i)
+    : i_(i), atEnd_(false)
+{
+    atEnd_ = Sentinel::check(dereference());
+}
+
+template <class Parser, class Sentinel, class Iterator>
+prefix_ Iterator satcom::pkf::impl::Parse_ListS_iterator<Parser,Sentinel,Iterator>::raw()
+    const
+{
+    return i_;
+}
+
+template <class Parser, class Sentinel, class Iterator>
+prefix_ Parser
+satcom::pkf::impl::Parse_ListS_iterator<Parser,Sentinel,Iterator>::dereference()
+    const
+{
+    return Parser(i_);
+}
+
+template <class Parser, class Sentinel, class Iterator>
+prefix_ bool satcom::pkf::impl::Parse_ListS_iterator<Parser,Sentinel,Iterator>::
+equal(Parse_ListS_iterator const & other)
+    const
+{
+    // !! We cannot compare the to iterators if either
+    // !! Iterator is atEnd_, since one of the iterators
+    // !! might be a default-constructed iterator and
+    // !! iterators can only be compared with each other
+    // !! if both point to the *same* valid container
+    if (atEnd_ || other.atEnd_) return atEnd_ == other.atEnd_;
+    return i_ == other.i_;
+}
+
+template <class Parser, class Sentinel, class Iterator>
+prefix_ void satcom::pkf::impl::Parse_ListS_iterator<Parser,Sentinel,Iterator>::increment()
+{
+    BOOST_ASSERT( !atEnd_ );
+    i_ += dereference().bytes();
+    atEnd_ = Sentinel::check(dereference());
+}
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>
+
+template <class Parser, class Sentinel, class Container>
+template <class P, class S, class I, class IP>
+prefix_ satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::
+Parse_ListS_wrapper(Parse_ListS<P,S,I,IP> const & list, Container & container)
+    : i_(list.i()-container.begin()), container_(container)
+{}
+
+template <class Parser, class Sentinel, class Container>
+prefix_ typename satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::size_type
+satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::size()
+    const
+{
+    return std::distance(begin(),end());
+}
+
+template <class Parser, class Sentinel, class Container>
+prefix_ bool satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::empty()
+    const
+{
+    return begin()==end();
+}
+
+template <class Parser, class Sentinel, class Container>
+prefix_ typename satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::iterator
+satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::begin()
+    const
+{
+    return iterator(container_.begin()+i_);
+}
+
+template <class Parser, class Sentinel, class Container>
+prefix_ typename satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::iterator
+satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::end()
+    const
+{
+    return iterator();
+}
+
+template <class Parser, class Sentinel, class Container>
+prefix_ typename satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::range_type
+satcom::pkf::Parse_ListS_wrapper<Parser,Sentinel,Container>::range()
+    const
+{
+    return std::make_pair(begin(),end());
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseListS.hh b/Packets/ParseListS.hh
new file mode 100644 (file)
index 0000000..2c75016
--- /dev/null
@@ -0,0 +1,165 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_ParseListS_
+#define HH_ParseListS_ 1
+
+// Custom includes
+#include <utility> // for std::pair
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/utility.hpp> // for boost::noncopyable
+#include "ParserBase.hh"
+
+//#include "ParseListS.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+
+    template <class Parser, class Sentinel, class Container> class Parse_ListS_wrapper;
+    namespace impl { 
+        template <class Parser, class Sentinel, class Container> class Parse_ListS_iterator; 
+    }
+
+    template <class Parser, class Sentinel, class Iterator=nil, class IPacket=nil>
+    struct Parse_ListS : public ParserBase<Iterator,IPacket>
+    {
+        ///////////////////////////////////////////////////////////////////////////
+        // Parser interface
+
+        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;
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Container interface
+
+        typedef typename Parser::template rebind<Iterator>::parser value_type;
+        typedef Sentinel sentinel;
+        typedef impl::Parse_ListS_iterator<value_type,sentinel,byte_iterator> iterator;
+        typedef unsigned size_type;
+        typedef int difference_type;
+        typedef std::pair<iterator,iterator> range_type;
+
+        template <class Container>
+        struct wrapper { typedef Parse_ListS_wrapper<value_type, Sentinel, Container> t; };
+
+        size_type size() const;
+        bool empty() const;
+
+        iterator begin() const;
+        iterator end() const;
+        range_type range() const;
+        range_type value() const;
+
+     private:
+        template <class P, class S, class C> friend class Parse_ListS_wrapper;
+    };
+
+    /** \brief
+        
+        Holds a reference to the container !
+      */
+    template <class Parser, class Sentinel, class Container>
+    class Parse_ListS_wrapper
+        : public boost::noncopyable
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef Container container;
+        typedef Sentinel sentinel;
+        typedef typename Parser::byte_iterator byte_iterator;
+        typedef Parser value_type;
+        typedef impl::Parse_ListS_iterator<value_type,sentinel,byte_iterator> iterator;
+        typedef unsigned size_type;
+        typedef int difference_type;
+        typedef std::pair<iterator,iterator> range_type;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        template <class P, class S, class I, class IP>
+        Parse_ListS_wrapper(Parse_ListS<P,S,I,IP> const & list, Container & container);
+
+        // no default constructor
+        // no copy
+        // default destructor
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Accessors
+        ///@{
+
+        size_type size() const;
+        bool empty() const;
+
+        iterator begin() const;
+        iterator end() const;
+        range_type range() const;
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+        ///\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(); 
+
+        ///@}
+
+    protected:
+
+    private:
+        
+        size_type i_;
+        Container & container_;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ParseListS.cci"
+#include "ParseListS.ct"
+#include "ParseListS.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseListS.ih b/Packets/ParseListS.ih
new file mode 100644 (file)
index 0000000..6dbeb24
--- /dev/null
@@ -0,0 +1,69 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_ParseListS_
+#define IH_ParseListS_ 1
+
+// Custom includes
+#include <boost/iterator/iterator_facade.hpp>
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+namespace impl {
+
+    template <class Parser, class Sentinel, class Iterator>
+    class Parse_ListS_iterator
+        : public boost::iterator_facade< Parse_ListS_iterator<Parser,Sentinel,Iterator>,
+                                         Parser,
+                                         boost::forward_traversal_tag,
+                                         Parser >
+    {
+    public:
+        Parse_ListS_iterator();
+        explicit Parse_ListS_iterator(Iterator const & i);
+        
+        Iterator raw() const;
+        
+    private:
+        friend class boost::iterator_core_access;
+
+        Parser dereference() const;
+        bool equal(Parse_ListS_iterator const & other) const;
+        void increment();
+
+        Iterator i_;
+        bool atEnd_;
+    };
+
+}}}
+
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseListS.test.cc b/Packets/ParseListS.test.cc
new file mode 100644 (file)
index 0000000..464b336
--- /dev/null
@@ -0,0 +1,174 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ParseListS.test.hh"
+//#include "ParseListS.test.ih"
+
+// Custom includes
+#include "ParseListS.hh"
+#include "ParseInt.hh"
+#include "ParseVec.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/assign.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+namespace {
+    template <class Value>
+    struct Sentinel_IsZero {
+        static bool check(Value v) { return v==0; }
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(parse_ListS_simple)
+{
+    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());
+    for (iterator c (data); *c; ++c) {
+        BOOST_REQUIRE( i!=e );
+        BOOST_CHECK_EQUAL( *c, *i );
+        ++i;
+    }
+    BOOST_CHECK( i==e );
+
+    BOOST_CHECK_EQUAL( l.bytes(), 5u );
+    BOOST_CHECK_EQUAL( l.size(), 4u );
+    BOOST_CHECK( !l.empty() );
+}
+
+namespace {
+    // LVec is a vector with the length living directly before the vector
+    template <class Parser, class SizeParser, class Iterator=nil, class IPacket=nil>
+    struct Parse_LVec
+        : public Parse_Vector<Parser, SizeParser,Iterator,IPacket>
+    {
+        template <class I=nil, class P=nil>
+        struct rebind { typedef Parse_LVec<Parser,SizeParser,I,P> parser; };
+        typedef typename SizeParser::template rebind<Iterator>::parser sizeParser;
+
+        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
+        // BEWARE .. this->i() points to the Vector not the SizeParser ... hrmpf ...
+        { return e>=this->i() && static_cast<unsigned>(e-this->i())+sizeParser::bytes() >= bytes(); }
+    };
+
+    template <class Array>
+    struct Sentinel_EmptyArray {
+        static bool check(Array a) { return a.empty(); }
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(parse_ListS_complex)
+{
+    unsigned char data[] = { 0x02, 0x01, 0x02,
+                             0x03, 0x11, 0x12, 0x13,
+                             0x04, 0x21, 0x22, 0x23, 0x24,
+                             0x00 };
+
+    typedef unsigned char * iterator;
+    typedef Parse_LVec<Parse_UInt8<>,Parse_UInt8<>,iterator> Parse_UInt8LVec;
+    typedef Parse_ListS<Parse_UInt8LVec,Sentinel_EmptyArray<Parse_UInt8LVec>,iterator> Parse_UInt8LVecListS;
+
+    Parse_UInt8LVecListS l (data);
+    BOOST_CHECK( l.check(data+13) );
+
+    Parse_UInt8LVecListS::iterator i (l.begin());
+    Parse_UInt8LVecListS::iterator e (l.end());
+    for (unsigned n (0); n<3; ++n) {
+        BOOST_REQUIRE( i!=e );
+        BOOST_CHECK_EQUAL( i->size(), n+2 );
+        Parse_UInt8LVec::iterator j (i->begin());
+        Parse_UInt8LVec::iterator je (i->end());
+        for (unsigned m (0); m<n+2; ++m, ++j) {
+            BOOST_CHECK( j!=je );
+            BOOST_CHECK_EQUAL( static_cast<unsigned>(*j), 16*n+m+1 );
+        }
+        BOOST_CHECK( j==je );
+        ++i;
+    }
+    BOOST_CHECK( i==e );
+    
+    BOOST_CHECK_EQUAL( l.size(), 3u );
+    BOOST_CHECK_EQUAL( l.bytes(), 13u );
+    BOOST_CHECK( !l.empty() );
+}
+
+BOOST_AUTO_UNIT_TEST(parse_ListS_wrapper)
+{
+    typedef std::vector<unsigned char> Container;
+    typedef Container::iterator iterator;
+    typedef Parse_LVec<Parse_UInt8<>,Parse_UInt8<>,iterator> Parse_UInt8LVec;
+    typedef Parse_ListS<Parse_UInt8LVec, Sentinel_EmptyArray<Parse_UInt8LVec>,iterator> Parse_UInt8LVecListS;
+    typedef Parse_UInt8LVecListS::wrapper<Container>::t Parse_UInt8LVecListSWrap;
+
+    using namespace boost::assign;
+
+    Container data;
+    data +=
+        0x02, 0x01, 0x02,
+        0x03, 0x11, 0x12, 0x13,
+        0x04, 0x21, 0x22, 0x23, 0x24,
+        0x00;
+
+    Parse_UInt8LVecListS l (data.begin());
+    Parse_UInt8LVecListSWrap w (l,data);
+
+    BOOST_CHECK_EQUAL( w.size(), 3u );
+    BOOST_CHECK ( !w.empty() );
+    BOOST_CHECK ( w.begin() != w.end() );
+    BOOST_CHECK ( w.range() == std::make_pair(w.begin(), w.end()) );
+
+#if 0
+    unsigned char newdata[] = { 0x01, 0x00 };
+
+    w.insert(w.begin(),Parse_UInt8LVec::rebind<unsigned char*>::parser(newdata));
+    BOOST_CHECK_EQUAL( w.size(), 4u );
+    BOOST_CHECK_EQUAL( w.begin()->size(), 1u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>((*w.begin())[0]), 0x00u );
+#endif
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseVec.ct b/Packets/ParseVec.ct
new file mode 100644 (file)
index 0000000..a34f1c9
--- /dev/null
@@ -0,0 +1,81 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template funPacketRegistry.ons
+
+//#include "ParseVec.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class Parser, class SizeParser, class Container>
+template <class Value>
+prefix_ void
+satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::insert(iterator pos,
+                                                                       Value const & t)
+{
+    size_type ix(pos.raw()-container_.begin());
+    shift(pos);
+    Parser(container_.begin()+ix).value(t);
+}
+
+template <class Parser, class SizeParser, class Container>
+template <class Value>
+prefix_ void
+satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::insert(iterator pos,
+                                                                       size_type n,
+                                                                       Value const & t)
+{
+    size_type ix(pos.raw()-container_.begin());
+    shift(pos,n);
+    typename Container::iterator j (container_.begin()+ix);
+    for (; n; --n, j+=Parser::bytes()) 
+        Parser(j).value(t);
+}
+
+template <class Parser, class SizeParser, class Container>
+template <class InputIterator>
+prefix_ void
+satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::insert(iterator pos,
+                                                                       InputIterator f,
+                                                                       InputIterator l)
+{
+    // FIXME: This is HORRIBLY inefficient ... we need to specialize 
+    // for random_aPacketRegistry.ess and forward iterators, where we can count the distance
+
+    size_type ix(pos.raw()-container_.begin());
+    for (;f!=l;++f) {
+        insert(container_.begin()+ix,*f);
+        ix += Parser::bytes();
+    }
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseVec.cti b/Packets/ParseVec.cti
new file mode 100644 (file)
index 0000000..86f282f
--- /dev/null
@@ -0,0 +1,224 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "ParseVec.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::
+Parse_Vector(SizeParser const & size)
+    : size_(size) 
+{}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::
+Parse_Vector(size_parser const & size, Iterator const & i)
+    : ParserBase<Iterator,IPacket>(i), size_(size) 
+{}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ unsigned satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::bytes()
+    const
+{
+    return Parser::bytes()*size();
+}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ void
+satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::check(Iterator const & e)
+    const
+{
+    return e-this->i() >= bytes();
+}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ void satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::init()
+    const
+{
+    iterator e (end());
+    for (iterator i (begin()); i!=e; ++i) i->init();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ typename satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::size_type
+satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::size()
+    const
+{
+    return size_.value();
+}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ bool satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::empty()
+    const
+{
+    return size()==0;
+}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ 
+typename satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::iterator
+satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::begin()
+    const
+{
+    return iterator(this->i());
+}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ 
+typename satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::iterator
+satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::end()
+    const
+{
+    return iterator(this->i()+bytes());
+}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ 
+typename satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::range_type
+satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::range()
+    const
+{
+    return std::make_pair(begin(),end());
+}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ 
+typename satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::range_type
+satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::value()
+    const
+{
+    return range();
+}
+
+template <class Parser, class SizeParser, class Iterator, class IPacket>
+prefix_ 
+typename satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::value_type
+satcom::pkf::Parse_Vector<Parser,SizeParser,Iterator,IPacket>::operator[](difference_type i)
+    const
+{
+    return begin()[i];
+}
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>
+
+template <class Parser, class SizeParser, class Container>
+template <class P, class SP, class I, class IP>
+prefix_ satcom::pkf::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) 
+{}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ typename satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::size_type
+satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::size()
+    const
+{
+    return SizeParser(container_.begin()+size_i_).value();
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ bool satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::empty()
+    const
+{
+    return size() == 0;
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ typename satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::iterator
+satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::begin()
+    const
+{
+    return iterator(container_.begin() + i_);
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ typename satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::iterator
+satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::end()
+    const
+{
+    return iterator(container_.begin() + i_ + Parser::bytes()*size());
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ typename satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::range_type
+satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::range()
+    const
+{
+    return std::make_pair(begin(), end());
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ typename satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::value_type
+satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::operator[](difference_type i)
+    const
+{
+    return begin()[i];
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ void satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::shift(iterator pos,
+                                                                               size_type n)
+{
+    container_.insert(pos.raw(),n*Parser::bytes(),0);
+    SizeParser(container_.begin()+size_i_) += n;
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ void satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::erase(iterator pos,
+                                                                               size_type n)
+{
+    container_.erase(pos.raw(),pos.raw()+n*Parser::bytes());
+    SizeParser(container_.begin()+size_i_) -= n;
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ void satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::erase(iterator f,
+                                                                               iterator l)
+{
+    erase(f,l-f);
+}
+
+template <class Parser, class SizeParser, class Container>
+prefix_ void satcom::pkf::Parse_Vector_wrapper<Parser,SizeParser,Container>::clear()
+{
+    container_.erase(container_.begin()+i_,container_.begin()+i_+size()*Parser::bytes());
+    SizeParser(container_.begin()+size_i_) = 0;
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseVec.hh b/Packets/ParseVec.hh
new file mode 100644 (file)
index 0000000..3b2dc38
--- /dev/null
@@ -0,0 +1,175 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_ParseVec_
+#define HH_ParseVec_ 1
+
+// Custom includes
+#include <utility> // for std::pair
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/utility.hpp> // for boost::noncopyable
+#include "ParserBase.hh"
+#include "ParseArray.hh" // for Parse_Array_iterator
+
+//#include "ParseVec.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+
+    template <class Parser, class SizeParser, class Container> class Parse_Vector_wrapper;
+
+    template <class Parser, class SizeParser, class Iterator=nil, class IPacket=nil>
+    struct Parse_Vector : public ParserBase<Iterator,IPacket>
+    {
+        typedef typename SizeParser::template rebind<Iterator>::parser size_parser;
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Parser interface
+
+        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;
+
+        ///////////////////////////////////////////////////////////////////////////
+        // Container interface
+
+        typedef typename Parser::template rebind<Iterator>::parser value_type;
+        typedef impl::Parse_Array_iterator<value_type,Iterator> iterator;
+        typedef unsigned size_type;
+        typedef int difference_type;
+        typedef std::pair<iterator,iterator> range_type;
+
+        template <class Container>
+        struct wrapper { typedef Parse_Vector_wrapper<value_type, size_parser, Container> t; };
+
+        size_type size() const;
+        bool empty() const;
+
+        iterator begin() const;
+        iterator end() const;
+        range_type range() const;
+        range_type value() const;
+
+        value_type operator[](difference_type i) 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>
+    class Parse_Vector_wrapper
+        : public boost::noncopyable
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef Container container;
+        typedef SizeParser size_parser;
+        typedef typename Parser::byte_iterator byte_iterator;
+        typedef Parser value_type;
+        typedef impl::Parse_Array_iterator<value_type,byte_iterator> iterator;
+        typedef unsigned size_type;
+        typedef int difference_type;
+        typedef std::pair<iterator,iterator> range_type;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        template <class P, class SP, class I, class IP>
+        Parse_Vector_wrapper(Parse_Vector<P,SP,I,IP> const & vector, Container & container);
+
+        // no default constructor
+        // no copy
+        // default destructor
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name APacketRegistry.essors
+        ///@{
+
+        size_type size() const;
+        bool empty() const;
+
+        iterator begin() const;
+        iterator end() const;
+        range_type range() const;
+
+        value_type operator[](difference_type i) const;
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Mutators
+        ///@{
+
+        void shift(iterator pos, size_type n=1); 
+        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_;
+        size_type size_i_;
+        Container & container_;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ParseVec.cci"
+#include "ParseVec.ct"
+#include "ParseVec.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParseVec.test.cc b/Packets/ParseVec.test.cc
new file mode 100644 (file)
index 0000000..4743c2a
--- /dev/null
@@ -0,0 +1,153 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ParseVec.test.hh"
+//#include "ParseVec.test.ih"
+
+// Custom includes
+#include "ParseVec.hh"
+#include "ParseInt.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/assign.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+BOOST_AUTO_UNIT_TEST(parseVec_test)
+{
+    unsigned char data[] = { 0x03,                                   // size
+                             0x10, 0x11,  0x12, 0x13,  0x14, 0x15,   // data
+                             0x20, 0x21,  0x22, 0x23,  0x24, 0x25 };
+    typedef unsigned char * iterator;
+    typedef Parse_Vector<Parse_UInt16<>,Parse_UInt8<>,iterator> Parse_UInt16Vec;
+
+    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 );
+    BOOST_CHECK_EQUAL( v.bytes(), 6u );
+    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());
+    for (;j!=e;++j, i+=2)
+        BOOST_CHECK_EQUAL( Parse_UInt16<iterator>(i), *j );
+    BOOST_CHECK_EQUAL(i, data+13);
+}
+
+BOOST_AUTO_UNIT_TEST(parseVec_wrapper)
+{
+    typedef std::vector<unsigned char> Container;
+    typedef Container::iterator iterator;
+    typedef Parse_UInt8<iterator> Parse_Size;
+    typedef Parse_Vector<Parse_UInt16<>,Parse_Size,iterator> Parse_UInt16Vec;
+    typedef Parse_UInt16Vec::wrapper<Container>::t Parse_UInt16VecWrap;
+
+    using namespace boost::assign;
+    
+    Container data;
+    data += 
+        0x03,                                   // size
+        0x10, 0x11,  0x12, 0x13,  0x14, 0x15,   // data
+        0x20, 0x21,  0x22, 0x23,  0x24, 0x25;
+
+    Parse_Size sizeParser (data.begin());
+    Parse_UInt16Vec v (sizeParser, data.begin()+1);
+    Parse_UInt16VecWrap w (v,data);
+
+    BOOST_CHECK_EQUAL( w[0], 0x1011 );
+    BOOST_CHECK_EQUAL( w[2], 0x1415 );
+    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());
+        Parse_UInt16VecWrap::iterator e (w.end());
+        for (;j!=e;++j, i+=2)
+            BOOST_CHECK_EQUAL( Parse_UInt16<iterator>(i), *j );
+        BOOST_CHECK_EQUAL(data.end()-i, 0);
+    }
+
+    w.shift(w.begin()+1);
+    BOOST_CHECK_EQUAL( w.size(), 7u );
+    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 );
+    BOOST_CHECK_EQUAL( w[3], 0xfffe );
+    BOOST_CHECK_EQUAL( w[4], 0xfffe );
+    BOOST_CHECK_EQUAL( w[5], 0x1415 );
+
+    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 );
+
+    {
+        iterator i (data.begin()+1);
+        Parse_UInt16VecWrap::iterator j (w.begin());
+        Parse_UInt16VecWrap::iterator e (w.end());
+        for (;j!=e;++j, i+=2)
+            BOOST_CHECK_EQUAL( Parse_UInt16<iterator>(i), *j );
+        BOOST_CHECK_EQUAL(data.end()-i, 0);
+    }
+
+    w.clear();
+    BOOST_CHECK_EQUAL( w.size(), 0u );
+    BOOST_CHECK( w.begin() == w.end() );
+    BOOST_CHECK_EQUAL( data.size(), 1u );
+}
+
+// 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 
+    // it's compile-time ...
+    BOOST_CHECK( Parser_traits< Parse_UInt32<> >::fixed_size );
+    BOOST_CHECK( (! Parser_traits< Parse_Vector< Parse_UInt16<>,Parse_UInt16<> > >::fixed_size) );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParserBase.cti b/Packets/ParserBase.cti
new file mode 100644 (file)
index 0000000..5ba7367
--- /dev/null
@@ -0,0 +1,96 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "ParserBase.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Iterator, class IPacket>
+prefix_ Iterator satcom::pkf::ParserBase<Iterator,IPacket>::i()
+    const
+{
+    return static_cast<IPacket const *>(this)->begin();
+}
+
+template <class Iterator>
+prefix_ satcom::pkf::ParserBase<Iterator,satcom::pkf::nil>::ParserBase(Iterator const & i)
+    : i_(i)
+{}
+
+template <class Iterator>
+prefix_ Iterator satcom::pkf::ParserBase<Iterator,satcom::pkf::nil>::i()
+    const
+{
+    return i_;
+}
+
+template <class Parser, class Iterator>
+prefix_ bool satcom::pkf::impl::check(Iterator const & b, Iterator const & e,
+                                      impl::ParserBase *)
+{
+    return impl::ParserCheck<Parser,Parser_traits<Parser>::fixed_size>::check(b,e);
+}
+
+template <class Parser, class Iterator>
+prefix_ bool satcom::pkf::impl::check(Iterator const & b, Iterator const & e,
+                                      void *)
+{
+    return Parser::check(b,e);
+}
+
+template <class Parser, class Iterator>
+prefix_ bool satcom::pkf::check(Iterator const & b, Iterator const & e)
+{
+    return impl::check<Parser,Iterator>(b,e,static_cast<Parser*>(0));
+}
+
+template <class Parser>
+prefix_ unsigned satcom::pkf::impl::min_bytes(impl::ParserBase *)
+{
+    return impl::ParserMinBytes<Parser,Parser_traits<Parser>::fixed_size>::bytes();
+}
+
+template <class Parser>
+prefix_ unsigned satcom::pkf::impl::min_bytes(void *)
+{
+    return 0;
+}
+
+template <class Parser>
+prefix_ unsigned satcom::pkf::min_bytes()
+{
+    return impl::min_bytes<Parser>(static_cast<Parser*>(0));
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParserBase.hh b/Packets/ParserBase.hh
new file mode 100644 (file)
index 0000000..69508b7
--- /dev/null
@@ -0,0 +1,296 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief Parser framework
+ */
+
+#ifndef HH_ParserBase_
+#define HH_ParserBase_ 1
+
+// Custom includes
+#include <utility>
+#include <boost/type_traits/is_member_function_pointer.hpp>
+
+#include "ParserBase.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+    
+    namespace impl { struct ParserBase; }
+
+    struct nil {};
+
+    /** \brief Parser framework
+
+        This class is the baseclass for all parser classes of the
+        parser framework. The parser framework is used to interpret
+        byte-oriented data from arbitrary random access iterators. The
+        framework is hierarchical in the sense, that parsers can be
+        arbitrarily nested.
+
+        All parser framework classes are as lightweight as
+        possible. Most parser classes only have a single iterator as
+        data member and (depending on the container) therefore have
+        the same size as a single pointer. Parsers are therefore
+        conceptually and in essence simply pointers decorated with
+        type information.
+
+        It is very important for parser classes to be lightweight and
+        to have only simple constructors since parsers are passed
+        around by value. Parser instances most of the time are
+        temporaries. However, since they are only 'decorated'
+        pointers, this should not have any performance impact.
+
+        To implement a new parser, write a template implementing the
+        following members:
+        
+        \code
+            template <class Iterator=nil, class IPacket=nil>
+            struct Parser_Example
+                : protected satcom::pkf::ParserBase<Iterator,IPacket>
+            {
+                // fixed interface of all parser classes
+
+                template <class I=nil, class P=nil>
+                struct rebind { typedef Parse_Example<I,P> parser; }
+                typedef Iterator byte_iterator;
+
+                Parse_Example() {}
+                Parse_Example(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+        
+                [static] unsigned bytes()
+                {
+                    // return the size of the parsed header. This
+                    // method must be declared static if the size is
+                    // constant, otherwise it must be a non-static
+                    // member
+                    return 14;
+                }
+
+                static bool check(Iterator const & begin, Iterator const & end)
+                {
+                    BOOST_ASSERT( end>=begin );
+                    // return true, if the data in the range [begin,end)
+                    // can be safely interpreted by the parser without
+                    // causing invalid memory access. This means,
+                    // check, wether the data is truncated
+                    return static_cast<unsigned>(end-begin) >= bytes();
+                }
+
+                // optional, only needed if bytes() is non-static
+                static unsigned min_bytes()
+                {
+                    // return the minimum size of the header. This
+                    // is the amount of space needed to allocate
+                    // an otherwise empty packet
+                    return 10;
+                }
+
+                // optional
+                void init()
+                {
+                    // initialize the packet if necessary
+                }
+
+                // optional
+                void init(Iterator b, Iterator e)
+                {
+                    // initialize the packet with given payload
+                }
+
+                // example methods to parse fields
+
+                typedef Parse_UInt16 < Iterator >                    Parse_Field1;
+                typedef Parse_Array  < 3, Parse_UInt32<>, Iterator > Parser_Field2
+
+                Parse_Field1 field1() const { return Parse_Field1 (this->i()); }
+                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
+          template parameters. These parameters must then be added in
+          front of the standard parameters. The rebind structure must
+          however always have only two parameters. Additional
+          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.
+
+        - unsigned bytes() member: This member must return the number
+          of bytes the parser interprets. This will be the size of the
+          implemented header. If the header has a fixed size, this
+          member must be static, if it is dynamic the member must be
+          non-static
+
+        - static bool check(Iterator b, Iterator e) member: This
+          method must return true \e only if the range [b,e) contains
+          a \e complete packet, that is, e-b >= bytes(). However, the
+          call to bytes() might involve accessing data bytes which
+          might not exist. The bytes() call cannot check this (it has
+          no access to the \e end of the valid range). To keep the
+          performance up, the validity check is performed once. The
+          parser has to ensure, that validity is maintained even when
+          changing the values. Validity in this context does not
+          imply, that the packet is semantically correct, it only
+          implies, that the packet can be parsed without risking
+          invalid memory access.
+
+        - The min_bytes() member is optional. It is only used, if the
+          Parser implements a non-fixed-size Packet, that is, if the
+          bytes() member is non-static. In this case, min_bytes() has
+          to be implemented and must return the amount of space
+          necessary to construct an empty instance. The construction
+          will proceed by first allocating the necessary space
+          somewhere, initializing this space with all zeros. Then a
+          Parser instance is created at that space and the Parsers
+          init() method is called.
+
+        - The init() member is optional. If all-zero initialization of
+          a new Packet is enough, this member can be
+          skipped. Otherwise, the init() member can assume to have
+          access to a min_buytes() sized area which is all-zero
+          initialized.
+
+        - The init(Packet::ptr payload) member is optional. By default
+          it just calls the init() member. Here, special
+          initialization regarding the payload may be done. As for
+          min_bytes(Packet::ptr), the argument type is allowed to be
+          templatized or may be a specific packet ptr thereby
+          restricting the permissible payload packet types.
+
+        - The parser then contains any additional methods to parse the
+          header constituents.
+
+        ParserBase provides the parser classes with access to the
+        packet iterator. This class is templatized on the Iterator
+        type and an optional baseclass type.
+
+        If the baseclass is given, it is used to access the iterator
+        directly using 'begin'. If it is not given, the instance has
+        to be constructed with an iterator.
+
+        This implementation ensures, that a parser can either be
+        inherited into a Packet class or be used as a temporary.
+      */
+    template <class Iterator, class IPacket=nil>
+    class ParserBase : public impl::ParserBase
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+        
+        // default default constructor
+        // default copy constructor
+        // default copy assignment
+        // default destructor
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        Iterator i() const;
+        static void init() {};
+
+    private:
+        
+    };
+
+    template <class Iterator>
+    class ParserBase<Iterator,nil> : public impl::ParserBase
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        explicit ParserBase(Iterator const & i);
+
+        // no default constructor
+        // default copy constructor
+        // default copy assignment
+        // default destructor
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        Iterator i() const;
+        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
+        true if and only if the Parser has a static bytes() member.
+     */
+    template <class Parser>
+    struct Parser_traits {
+        typedef Parser parser;
+        typedef typename Parser::byte_iterator byte_iterator;
+        static const bool fixed_size = impl::Parser_traits_fixed_size<Parser>::fixed_size;
+
+        template <class I=nil, class P=nil>
+        struct rebind {
+            typedef typename Parser::template rebind<I,P>::parser parser;
+        };
+    };
+
+    template <class Parser, class Iterator>
+    bool check(Iterator const & b, Iterator const & e);
+
+    template <class Parser>
+    unsigned min_bytes();
+    
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ParserBase.cci"
+//#include "ParserBase.ct"
+#include "ParserBase.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParserBase.ih b/Packets/ParserBase.ih
new file mode 100644 (file)
index 0000000..3cb5eb1
--- /dev/null
@@ -0,0 +1,99 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_ParserBase_
+#define IH_ParserBase_ 1
+
+// Custom includes
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+namespace impl {
+
+    struct ParserBase {};
+
+    template <unsigned N>
+    struct Parser_traits_sentinel
+    { int v[N]; };
+
+    template <class Parser>
+    struct Parser_traits_fixed_size {
+        // This differentiates between bytes being a static or
+        // non-static member of Parser ...
+        static const bool fixed_size = sizeof(
+            Parser_traits_fixed_size_check(&Parser::bytes))-sizeof(Parser_traits_sentinel<1>);
+    };
+
+    template <class T>
+    Parser_traits_sentinel<2> Parser_traits_fixed_size_check(T);
+
+    template <class R,class T>
+    Parser_traits_sentinel<1> Parser_traits_fixed_size_check(R (T::*)());
+
+    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) 
+            { 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 *);
+
+    template <class Parser, bool Fixed>
+    struct ParserMinBytes {
+        static unsigned bytes() { return Parser::min_bytes(); }
+    };
+
+    template <class Parser>
+    struct ParserMinBytes<Parser,true> {
+        static unsigned bytes() { return Parser::bytes(); }
+    };
+
+}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/ParserBase.test.cc b/Packets/ParserBase.test.cc
new file mode 100644 (file)
index 0000000..dca6b77
--- /dev/null
@@ -0,0 +1,104 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ParserBase.test.hh"
+//#include "ParserBase.test.ih"
+
+// Custom includes
+#include "ParserBase.hh"
+#include "Packet.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace pkf = satcom::pkf;
+
+// The non-inherited Version is extensively tested in PaseInt.test.hh
+
+BOOST_AUTO_UNIT_TEST(parserBase_inherited)
+{
+    // TODO: Implement
+}
+
+namespace {
+
+    template <class Iterator=pkf::nil, class IPacket=pkf::nil>
+    struct Parse_Test : public pkf::ParserBase<Iterator,IPacket>
+    {
+        template <class I=pkf::nil, class P=pkf::nil>
+        struct rebind { typedef Parse_Test<I,P> parser; };
+        typedef Iterator byte_iterator;
+        
+        Parse_Test() {}
+        Parse_Test(Iterator const & i) : pkf::ParserBase<Iterator,IPacket>(i) {}
+        
+        static unsigned bytes() { return 14; }
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    };
+
+    template <class Iterator=pkf::nil, class IPacket=pkf::nil>
+    struct Parse_Test2 : public pkf::ParserBase<Iterator,IPacket>
+    {
+        template <class I=pkf::nil, class P=pkf::nil>
+        struct rebind { typedef Parse_Test<I,P> parser; };
+        typedef Iterator byte_iterator;
+        
+        Parse_Test2() {}
+        Parse_Test2(Iterator const & i) : pkf::ParserBase<Iterator,IPacket>(i) {}
+        
+        unsigned bytes() const { return 14; }
+        static unsigned check(Iterator a, Iterator b)
+            { return true; }
+        static unsigned min_bytes() { return 10; }
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    };
+
+}
+
+BOOST_AUTO_UNIT_TEST(parserBase_construction)
+{
+    BOOST_CHECK_EQUAL( pkf::min_bytes< Parse_Test<int> >(), 14u );
+    BOOST_CHECK( pkf::check< Parse_Test<int> >(0,14) );
+    BOOST_CHECK( ! pkf::check< Parse_Test<int> >(2,15) );
+
+    BOOST_CHECK_EQUAL( pkf::min_bytes< Parse_Test2<int> >(), 10u );
+    BOOST_CHECK( pkf::check< Parse_Test2<int> >(2,13) );
+    BOOST_CHECK( pkf::check< Parse_Test2<int> >(2,12) );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/RTCPPacket.cc b/Packets/RTCPPacket.cc
new file mode 100644 (file)
index 0000000..f50b44d
--- /dev/null
@@ -0,0 +1,51 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "RTCPPacket.hh"
+//#include "RTCPPacket.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+
+prefix_ void satcom::pkf::RTCPPacket::v_nextInterpreter()
+    const
+{
+    registerInterpreter<DataPacket>(begin()+bytes(),end());
+}
+
+prefix_ void satcom::pkf::RTCPPacket::v_finalize()
+{}
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/RTCPPacket.cti b/Packets/RTCPPacket.cti
new file mode 100644 (file)
index 0000000..a652af0
--- /dev/null
@@ -0,0 +1,44 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "RTCPPacket.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Arg>
+prefix_ satcom::pkf::RTCPPacket::RTCPPacket(Arg const & arg)
+    : Packet(arg)
+{}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/RTCPPacket.hh b/Packets/RTCPPacket.hh
new file mode 100644 (file)
index 0000000..2518110
--- /dev/null
@@ -0,0 +1,315 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.b
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_RTCPPacket_
+#define HH_RTCPPacket_ 1
+
+// Custom includes
+#include "Packet.hh"
+#include "ParseInt.hh"
+#include "ParseArray.hh"
+#include "ParseListS.hh"
+#include "ParseVec.hh"
+#include "PacketRegistry.hh"
+
+//#include "RTCPPacket.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+
+    template <class I=nil,class P=nil> struct Parse_RTCP_RR;
+    template <class I=nil,class P=nil> struct Parse_RTCP_SR;
+    template <class I=nil,class P=nil> struct Parse_RTCP_SDES;
+    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>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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_UInt16     < Iterator >          Parse_Length;
+
+        typedef Parse_RTCP_RR    < Iterator >          Parse_RTCP_RR;
+        typedef Parse_RTCP_SR    < Iterator >          Parse_RTCP_SR;
+        typedef Parse_RTCP_SDES  < Iterator >          Parse_RTCP_SDES;
+        typedef Parse_RTCP_BYE   < Iterator >          Parse_RTCP_BYE;
+        typedef Parse_RTCP_APP   < Iterator >          Parse_RTCP_APP;
+
+        Parse_Version  version()      const { return Parse_Version  (this->i()      ); }
+        Parse_P        padding()      const { return Parse_P        (this->i()      ); }
+        Parse_Count    count()        const { return Parse_Count    (this->i()      ); }
+        Parse_PT       payloadType()  const { return Parse_PT       (this->i() + 1  ); }
+        Parse_Length   length()       const { return Parse_Length   (this->i() + 2  ); }
+
+        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_APP  app()  { return Parse_RTCP_APP  (this->i()  ); }
+        ///////////////////////////////////////////////////////////////////////////
+
+        unsigned int bytes() const { return 32 + (4 * length()); }
+        static bool check(Iterator const & b, Iterator const & e)
+        { return e-b >= 4 and unsigned(e-b) >= Parse_RTCP<Iterator>(b).bytes(); }
+
+    };
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_RTCP_RB : public ParserBase<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP_RB<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        Parse_RTCP_RB() {}
+        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; 
+
+        Parse_32bit   ssrc()        const { return Parse_32bit(this->i()   ); }
+        Parse_8bit    fragLost()    const { return Parse_8bit(this->i()+4  ); }
+        Parse_24bit   cnpl()        const { return Parse_24bit(this->i()+5 ); }
+        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; }
+
+    };
+
+    template <class Iterator, class IPacket>
+    struct Parse_RTCP_RR : public Parse_RTCP<Iterator, IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP_RR<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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 ); } 
+
+    };
+
+    template <class Iterator, class IPacket>
+    struct Parse_RTCP_SR : public Parse_RTCP<Iterator, IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP_SR<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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>
+    struct Parse_RTCP_item : public Parse_RTCP<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP_item<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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_desc   desc()         const { return Parse_desc(this->length(), this->i()+2 ); }
+
+
+
+    };
+
+    template <class List>
+    struct Sentinel_EmptyList {
+        static bool check(List a) { return a.empty(); }
+    };
+
+    template  <class Iterator=nil, class IPacket=nil>
+    struct Parse_RTCP_chunk : public Parse_RTCP<Iterator, IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP_chunk<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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 ); }
+    };
+
+
+    template <class Iterator, class IPacket>
+    struct Parse_RTCP_SDES : public Parse_RTCP<Iterator, IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP_SDES<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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>
+    struct Parse_RTCP_BYE : public Parse_RTCP<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP_BYE<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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 ); }
+
+    };
+
+
+    template <class Iterator, class IPacket>
+    struct Parse_RTCP_APP : public Parse_RTCP<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTCP_APP<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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;        
+
+        Parse_32bit   ssrc()       const { return Parse_32bit(this->i()+4); }
+        Parse_32bit   name()       const { return Parse_32bit(this->i()+8); }
+// this->length()-3
+        Parse_dataVec appData()    const { return Parse_dataVec(this->length(), this->i()+12 ); }
+
+    };
+
+
+    class RTCPPacket
+        : public Packet, 
+          public Parse_RTCP<Packet::iterator, RTCPPacket>
+    {
+        using Packet::registerInterpreter;
+       
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<RTCPPacket>::ptr ptr;
+
+    private:
+        template <class Arg>
+        RTCPPacket(Arg const & arg);
+
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+
+        friend class Packet;
+    };
+}}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "RTCPPacket.cci"
+//#include "RTCPPacket.ct"
+#include "RTCPPacket.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/RTCPPacket.test.cc b/Packets/RTCPPacket.test.cc
new file mode 100644 (file)
index 0000000..86e0d0a
--- /dev/null
@@ -0,0 +1,339 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "RTCPPacket.test.hh"
+//#include "RTCPPacket.test.ih"
+
+// Custom includes
+#include "RTCPPacket.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+BOOST_AUTO_UNIT_TEST(rtcpPacket_parser)
+{
+
+    // RTCP RR (no RB)
+    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( static_cast<unsigned>(p_1.payloadType()), 200u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p_1.length()), 0x0006u );
+
+    BOOST_CHECK_EQUAL(p_1.rr().ssrc(),           0xe570aa18u );
+
+    BOOST_CHECK_EQUAL(p_1.rr().ntp_msb(),        0xc7c2b200u );
+    BOOST_CHECK_EQUAL(p_1.rr().ntp_lsb(),        0xc3d70e96u );
+    BOOST_CHECK_EQUAL(p_1.rr().timestamp(),      0x00u       );
+    BOOST_CHECK_EQUAL(p_1.rr().spcount(),        0x01u       );
+    BOOST_CHECK_EQUAL(p_1.rr().socount(),        0x0dc8u     );
+
+
+    // TODO RTCP RR
+    unsigned char data_2[] = { 
+                             0x82, 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,
+
+                             0x01, 0x02, 0x03, 0x04,
+                             0x05, 0x06, 0x07, 0x08,
+                             0x09, 0x10, 0x11, 0x12,
+                             0x13, 0x14, 0x15, 0x16,
+                             0x20, 0x21, 0x22, 0x23,
+
+                             0x99, 0x02, 0x03, 0x04,
+                             0x05, 0x06, 0x07, 0x08,
+                             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( static_cast<unsigned>(p_2.payloadType()), 200u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p_2.length()), 0x0006u );
+
+    BOOST_CHECK_EQUAL(p_2.rr().ssrc(),           0xe570aa18u );
+
+    BOOST_CHECK_EQUAL(p_2.rr().ntp_msb(),        0xc7c2b200u );
+    BOOST_CHECK_EQUAL(p_2.rr().ntp_lsb(),        0xc3d70e96u );
+    BOOST_CHECK_EQUAL(p_2.rr().timestamp(),      0x00u       );
+    BOOST_CHECK_EQUAL(p_2.rr().spcount(),        0x01u       );
+    BOOST_CHECK_EQUAL(p_2.rr().socount(),        0x0dc8u     );
+
+    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 );
+    BOOST_CHECK_EQUAL( p_2.rr().rbVec().begin()->ehsnr(),    0x09101112u  );
+    BOOST_CHECK_EQUAL( p_2.rr().rbVec().begin()->LSR(),      0x13141516u  );
+    BOOST_CHECK_EQUAL( p_2.rr().rbVec().begin()->DLSR(),     0x20212223u  );
+
+    typedef unsigned char * iterator;
+    typedef Parse_UIntField     < 3, 8, iterator >    Parse_Count;
+    typedef Parse_Vector        < Parse_RTCP_RB<>, Parse_Count, iterator > Parse_rbVec;
+
+    Parse_rbVec::iterator j_2 (p_2.rr().rbVec().begin());
+
+    BOOST_CHECK_EQUAL( j_2->ssrc(),     0x01020304u  );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(j_2->fragLost()), 0x05u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(j_2->cnpl()[0]), 0x06u );
+    BOOST_CHECK_EQUAL( j_2->ehsnr(),    0x09101112u  );
+    BOOST_CHECK_EQUAL( j_2->LSR(),      0x13141516u  );
+    BOOST_CHECK_EQUAL( j_2->DLSR(),     0x20212223u  );
+
+    ++j_2;
+
+    BOOST_CHECK_EQUAL( j_2->ssrc(),     0x99020304u  );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(j_2->fragLost()), 0x05u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(j_2->cnpl()[0]), 0x06u );
+    BOOST_CHECK_EQUAL( j_2->ehsnr(),    0x09101112u  );
+    BOOST_CHECK_EQUAL( j_2->LSR(),      0x13141516u  );
+    BOOST_CHECK_EQUAL( j_2->DLSR(),     0x20212223u  );
+
+
+
+
+
+
+    // RTCP SR
+    unsigned char data_3[] = { 
+                             0x82, 0xc9, 0x00, 0x06, 
+                             0xe5, 0x70, 0xaa, 0x18, 
+                             
+                             0x99, 0x02, 0x03, 0x04,
+                             0x05, 0x06, 0x07, 0x08,
+                             0x09, 0x10, 0x11, 0x12,
+                             0x13, 0x14, 0x15, 0x16,
+                             0x20, 0x21, 0x22, 0x23,
+
+                             0x01, 0x02, 0x03, 0x04,
+                             0x05, 0x06, 0x07, 0x08,
+                             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( 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;
+
+    Parse_rbVec::iterator j (p_3.rr().rbVec().begin());
+    BOOST_CHECK_EQUAL( j->ssrc(),     0x01020304u  );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(j->fragLost()), 0x05u );
+    BOOST_CHECK_EQUAL( j->ehsnr(),    0x09101112u  );
+    BOOST_CHECK_EQUAL( j->LSR(),      0x13141516u  );
+    BOOST_CHECK_EQUAL( j->DLSR(),     0x20212223u  );
+
+    ++j;
+
+#if 0
+    BOOST_CHECK_EQUAL( j->ssrc(),     0x99020304u  );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(j->fragLost()), 0x05u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(j->cnpl()[0]), 0x06u );
+    BOOST_CHECK_EQUAL( j->ehsnr(),    0x09101112u  );
+    BOOST_CHECK_EQUAL( j->LSR(),      0x13141516u  );
+    BOOST_CHECK_EQUAL( j->DLSR(),     0x20212223u  );
+#endif
+
+    // TODO RTCP SDES
+
+    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); 
+
+    BOOST_CHECK_EQUAL( p_4.version(),            2u          );
+    BOOST_CHECK_EQUAL( p_4.padding(),            0           );
+    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_EQUAL( p_4.sdes().chunkVec().size(),    0x01u      );
+#if 0
+    Parse_RTCP_SDES::Parse_itemList::iterator j_4 (p_4.sdes().chunkVec().begin());
+
+// TODO  -> ask Stefan
+
+ // BOOST_CHECK_EQUAL( p_4.sdes().chunkList()[0].ssrc(), 0xe570aa18u);
+ // BOOST_CHECK_EQUAL( p_4.sdes().chunkList()[0].itemList().size(), 0x01u);
+ // BOOST_CHECK( p_4.sdes().chunkList()[0].itemList().check(data_4+20) );
+ // BOOST_CHECK_EQUAL(p.sdes().chunkList()[0].chunkList().size(),  1);
+
+//item 
+//     typeField(), 0x01u
+//     length(), 0x09u
+//     desc(), 0x393031313335373637u
+
+#endif
+
+
+   // 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( static_cast<unsigned>(p_5.payloadType()), 203u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p_5.length()), 0x0006u );
+
+    BOOST_CHECK_EQUAL( p_5.bye().ssrcVec().size(),    0x02u  );
+
+    BOOST_CHECK_EQUAL( p_5.bye().ssrcVec()[0],     0x01020304u  );
+    BOOST_CHECK_EQUAL( p_5.bye().ssrcVec()[1],     0x05060708u  );
+
+
+   // 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( 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().appData().size(), 2u           );
+#endif
+    BOOST_CHECK_EQUAL( p_6.app().appData()[0],     0x09101112u  );
+    BOOST_CHECK_EQUAL( p_6.app().appData()[1],     0x08u        );
+
+}
+
+                     
+BOOST_AUTO_UNIT_TEST(rtcpPacket_packet)
+{
+#if 0
+    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( static_cast<unsigned>(p_1->payloadType()), 200u );
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(p_1->length()), 0x0006u );
+
+    BOOST_CHECK_EQUAL(p_1->rr().ssrc(),           0xe570aa18u );
+
+    BOOST_CHECK_EQUAL(p_1->rr().ntp_msb(),        0xc7c2b200u );
+    BOOST_CHECK_EQUAL(p_1->rr().ntp_lsb(),        0xc3d70e96u );
+    BOOST_CHECK_EQUAL(p_1->rr().timestamp(),      0x00u       );
+    BOOST_CHECK_EQUAL(p_1->rr().spcount(),        0x01u       );
+    BOOST_CHECK_EQUAL(p_1->rr().socount(),        0x0dc8u     );
+#endif
+   
+}
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/RTPPacket.cc b/Packets/RTPPacket.cc
new file mode 100644 (file)
index 0000000..593610a
--- /dev/null
@@ -0,0 +1,105 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "RTPPacket.hh"
+//#include "RTPPacket.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+
+prefix_ void satcom::pkf::RTPPacket::v_nextInterpreter()
+    const
+{
+
+    if(extension()){
+        Packet::registerInterpreter<RTPUnknownExtensionPacket>(begin()+bytes(),end());
+    }else{
+       
+       int paddingOctets = 0;
+        if(padding()){
+           paddingOctets = paddingOctet();
+       }
+        registerInterpreter(payloadType(),begin()+bytes(),end()-paddingOctets);
+    }
+}
+
+prefix_ void satcom::pkf::RTPPacket::v_finalize()
+{}
+
+prefix_ void satcom::pkf::RTPPacket::v_dump(std::ostream & os)
+    const
+{
+    os << "RTP:\n"
+       << "  version       : " << version() << "\n"
+       << "  padding       : " << padding() << "\n"
+       << "  extension     : " << extension() << "\n"
+       << "  csrc count    : " << csrcCount() << "\n"
+       << "  marker        : " << marker() << "\n"
+       << "  payload type  : " << payloadType() << "\n"
+       << "  sequence nr   : " << seqNumber() << "\n"
+       << "  timestamp     : " << timestamp() << "\n"
+       << "  ssrc          : " << ssrc() << "\n"
+       << "  csrc list     : <not shown>\n";
+}
+
+prefix_ void satcom::pkf::RTPExtensionBasePacket::v_nextInterpreter()
+    const
+{
+
+    // We don't want to inherit Parse_RTPExtensionBase to avoid
+    // virtual inheritance problems. Since we need the size of the
+    // extension, we just allocate ourselves a ExtensionBase parser
+
+    Parse_RTPExtensionBase<iterator> p (begin());
+    if (!p.check(begin(),end()))
+        throw TruncatedPacketException();
+
+    int paddingOctets = 0;
+    if(get_prev<RTPPacket>()->padding()){
+       paddingOctets = get_prev<RTPPacket>()->paddingOctet();
+    }
+    registerInterpreter(get_prev<RTPPacket>()->payloadType(),begin()+p.bytes(),end()-paddingOctets);
+}
+
+prefix_ void satcom::pkf::RTPExtensionBasePacket::v_dump(std::ostream & os)
+    const
+{
+    os << "RTP extension packet:\n"
+       << "  content not shown\n";
+}
+
+prefix_ void satcom::pkf::RTPUnknownExtensionPacket::v_finalize()
+{}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/RTPPacket.cti b/Packets/RTPPacket.cti
new file mode 100644 (file)
index 0000000..18633be
--- /dev/null
@@ -0,0 +1,56 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "RTPPacket.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Arg>
+prefix_ satcom::pkf::RTPPacket::RTPPacket(Arg const & arg)
+    : Packet(arg)
+{}
+
+template <class Arg>
+prefix_ satcom::pkf::RTPExtensionBasePacket::
+RTPExtensionBasePacket(Arg const & arg)
+    : Packet(arg)
+{}
+
+template <class Arg>
+prefix_ satcom::pkf::RTPUnknownExtensionPacket::
+RTPUnknownExtensionPacket(Arg const & arg)
+    : RTPExtensionBasePacket(arg)
+{}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/RTPPacket.hh b/Packets/RTPPacket.hh
new file mode 100644 (file)
index 0000000..9f4a6c7
--- /dev/null
@@ -0,0 +1,224 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.b
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_RTPPacket_
+#define HH_RTPPacket_ 1
+
+// Custom includes
+#include "Packet.hh"
+#include "ParseInt.hh"
+#include "ParseArray.hh"
+#include "ParseVec.hh"
+#include "PacketRegistry.hh"
+
+//#include "RTPPacket.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+    
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_RTP : public ParserBase<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTP<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        Parse_RTP() {}
+        Parse_RTP(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+                     
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef Parse_UIntField  < 0, 2, Iterator >    Parse_Version;
+        typedef Parse_Flag       < 2, Iterator >       Parse_P;
+        typedef Parse_Flag       < 3, Iterator >       Parse_X;
+        typedef Parse_UIntField  < 4, 8, Iterator >    Parse_CC;
+        typedef Parse_Flag       < 0, Iterator >       Parse_M;
+        typedef Parse_UIntField  < 1, 8, Iterator >    Parse_PT;
+        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_CC       csrcCount()    const { return Parse_CC       (this->i()      ); }
+        Parse_M        marker()       const { return Parse_M        (this->i() + 1  ); }
+        Parse_PT       payloadType()  const { return Parse_PT       (this->i() + 1  ); }
+        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 ); }  
+
+        
+        ///////////////////////////////////////////////////////////////////////////
+
+        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 {
+        typedef boost::uint16_t key_t;
+    };
+
+    class RTPPacket
+        : public Packet, 
+          public Parse_RTP<Packet::iterator, RTPPacket>, 
+          public PacketRegistryMixin<RTPTypes,RTPPacket>
+    {
+        using Packet::registerInterpreter;
+        using PacketRegistryMixin<RTPTypes,RTPPacket>::registerInterpreter;
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<RTPPacket>::ptr ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        typedef Parse_UInt8 < Packet::iterator >  Parse_paddingOctet;
+        
+        Parse_paddingOctet paddingOctet() const { 
+            return Parse_paddingOctet( end() -1 ); 
+        } 
+
+    private:
+        template <class Arg>
+        RTPPacket(Arg const & arg);
+
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+        virtual void v_dump(std::ostream & os) const;
+
+        friend class Packet;
+    };
+
+   
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_RTPExtensionBase : public ParserBase<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTPExtensionBase<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        Parse_RTPExtensionBase() {}
+        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(); }        
+        static bool check(Iterator const & b, Iterator const & e)
+        { return e-b>=4 && unsigned(e-b) >= Parse_RTPExtensionBase<Iterator>(b).bytes(); }
+
+
+    }; 
+
+    class RTPExtensionBasePacket 
+        : public Packet,
+          public PacketRegistryMixin<RTPTypes, RTPExtensionBasePacket>
+    {
+        using PacketRegistryMixin<RTPTypes,RTPExtensionBasePacket>::registerInterpreter;
+        using Packet::registerInterpreter;
+    public:
+         ///////////////////////////////////////////////////////////////////////////       
+         typedef ptr_t<RTPExtensionBasePacket>::ptr ptr;
+
+    protected:
+        template <class Arg>
+        RTPExtensionBasePacket(Arg const & arg);
+
+    private:
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize() = 0;
+        virtual void v_dump(std::ostream & os) const;
+
+        friend class Packet;
+
+    };
+
+
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_RTPUnknownExtension : public Parse_RTPExtensionBase<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_RTPUnknownExtension<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        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 ); }
+
+    };
+
+    class RTPUnknownExtensionPacket
+        : public RTPExtensionBasePacket,
+          public Parse_RTPUnknownExtension<Packet::iterator, RTPUnknownExtensionPacket>
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<RTPUnknownExtensionPacket>::ptr ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    private:
+        template <class Arg>
+        RTPUnknownExtensionPacket(Arg const & arg);
+
+        //virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+
+        friend class RTPExtensionBasePacket;
+        friend class Packet;
+    };
+
+}}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include RTPPacket.cci"
+//#include "RTPPacket.ct"
+#include "RTPPacket.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/RTPPacket.test.cc b/Packets/RTPPacket.test.cc
new file mode 100644 (file)
index 0000000..ff3a58d
--- /dev/null
@@ -0,0 +1,246 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "RTPPacket.test.hh"
+//#include "RTPPacket.test.ih"
+
+// Custom includes
+#include "RTPPacket.hh"
+
+#include "EthernetPacket.hh"
+#include "IpV4Packet.hh"
+#include "UDPPacket.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+BOOST_AUTO_UNIT_TEST(rtpPacket_parser)
+{
+    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 
+                             
+                           };                       
+
+    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.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()[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, 
+                             0x09, 0x0A, 0x0B, 0x0C,
+
+                             0x11, 0x12, 0x13, 0x14, // CSRC 1
+                             0x15, 0x16, 0x17, 0x18, // CSRC 2
+                             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->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->paddingOctet(),       3           );
+
+    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>() );
+
+    RTPUnknownExtensionPacket::ptr v (p->next()->as<RTPUnknownExtensionPacket>());
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(v->proDef()), 0x2021u );
+    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[] = { 
+
+                             // Ethernet
+                             0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // destination MAC
+                             0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,  // source 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,
+
+                             // UDP 
+                             0x01, 0x02, 0x03, 0x04,
+                             0x05, 0x06, 0x07, 0x08,
+
+                             // RTP
+                             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 
+                             
+                             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( p->destination()[3], 0x04 );
+    BOOST_CHECK_EQUAL( p->source()[0], 0x07 );
+    BOOST_CHECK_EQUAL( p->type(), 0x0800 );
+
+    // IP
+    BOOST_REQUIRE( p->next() );
+    BOOST_CHECK( p->next()->is<IpV4Packet>() );
+
+    IpV4Packet::ptr ip (p->next()->as<IpV4Packet>());
+
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(ip->protocol()), 0x11u );
+
+    // UDP
+    BOOST_REQUIRE( ip->next() );
+    BOOST_CHECK( ip->next()->is<UDPPacket>() );
+
+    UDPPacket::ptr udp (ip->next()->as<UDPPacket>());
+
+    BOOST_CHECK_EQUAL( udp->source(),            0x0102       );
+    BOOST_CHECK_EQUAL( udp->destination(),       0x0304       );
+    BOOST_CHECK_EQUAL( udp->length(),            0x0506       );
+    BOOST_CHECK_EQUAL( udp->crc(),               0x0708       ); 
+
+
+    // RTP
+    BOOST_REQUIRE( udp->next() );
+    BOOST_CHECK( udp->next()->is<DataPacket>() );
+
+    RTPPacket::ptr rtp (udp->next()->reinterpret<RTPPacket>());
+
+    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->marker(),             0           );
+    BOOST_CHECK_EQUAL( rtp->payloadType(),        0x02u       );
+    // the static_cast is to silence gcc-3.3
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(rtp->seqNumber()), 0x0304u );
+    BOOST_CHECK_EQUAL( rtp->timestamp(),          0x05060708u );
+    BOOST_CHECK_EQUAL( rtp->ssrc(),               0x090A0B0Cu );
+
+    BOOST_CHECK_EQUAL( rtp->paddingOctet(),       3           );
+
+    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>() );
+
+    RTPUnknownExtensionPacket::ptr ex (rtp->next()->as<RTPUnknownExtensionPacket>());
+    BOOST_CHECK_EQUAL( static_cast<unsigned>(ex->proDef()), 0x2021u );
+    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          );
+   
+}
+
+
+
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/SConscript b/Packets/SConscript
new file mode 100644 (file)
index 0000000..f322d3d
--- /dev/null
@@ -0,0 +1,9 @@
+Import('env')
+import SatSCons
+
+###########################################################################
+
+sources = SatSCons.GlobSources()
+SatSCons.StandardTargets(env)
+SatSCons.Lib(env, 'Packets',  sources)
+SatSCons.Doxygen(env,sources)
diff --git a/Packets/TODO b/Packets/TODO
new file mode 100644 (file)
index 0000000..8749617
--- /dev/null
@@ -0,0 +1,15 @@
+Klasse für IPv6 (v4?) Adressen als Parser und als value type
+
+Bessere check implementierung ?
+check umbauen: check() static machen und vor dem DerivedPacket() constructor
+aufrufen. DerivedPacket() constructor darf dann keine exception mehr
+auslösen
+
+ParseListS wrapper implementieren.
+
+---------------------------------------------------------------------------
+Obsolete:
+
+reference-counting: Packet's mit 0 refcount erstellen und dann in
+create hochzählen. Was spricht eigentlich dagegen ???
+  --> Hrmpf .. doch ziemlich kompliziert, ich glaube, das lasse ich
diff --git a/Packets/UDPPacket.cc b/Packets/UDPPacket.cc
new file mode 100644 (file)
index 0000000..7f44028
--- /dev/null
@@ -0,0 +1,66 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "UDPPacket.hh"
+//#include "UDPPacket.ih"
+#include "IpV4Packet.hh"
+
+// Custom includes
+#include "DataPacket.hh"
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+namespace {
+    namespace pkf = satcom::pkf;
+    pkf::PacketRegistry<pkf::IpV4Types>::RegistrationProxy<pkf::UDPPacket> 
+        registerUDPPacket(17);
+}
+
+prefix_ void satcom::pkf::UDPPacket::v_nextInterpreter()
+    const
+{
+    registerInterpreter<DataPacket>(begin()+bytes(),end());
+}
+
+prefix_ void satcom::pkf::UDPPacket::v_finalize()
+{}
+
+prefix_ void satcom::pkf::UDPPacket::v_dump(std::ostream & os)
+    const
+{
+    os << "UDP:\n"
+       << "  source port   : " << source() << "\n"
+       << "  dest port     : " << destination() << "\n"
+       << "  length        : " << length() << "\n"
+       << "  crc           : " << std::hex << crc() << std::dec << "\n";
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/UDPPacket.cti b/Packets/UDPPacket.cti
new file mode 100644 (file)
index 0000000..b49e530
--- /dev/null
@@ -0,0 +1,46 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "UDPPacket.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Arg>
+prefix_ satcom::pkf::UDPPacket::UDPPacket(Arg const & arg)
+    : Packet(arg)
+{}
+
+
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/UDPPacket.hh b/Packets/UDPPacket.hh
new file mode 100644 (file)
index 0000000..75cdf79
--- /dev/null
@@ -0,0 +1,96 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_UDPPacket_
+#define HH_UDPPacket_ 1
+
+// Custom includes
+#include "Packet.hh"
+#include "ParseInt.hh"
+#include "ParseArray.hh"
+#include "PacketRegistry.hh"
+
+//#include "UDPPacket.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace pkf {
+    
+    template <class Iterator=nil, class IPacket=nil>
+    struct Parse_UDP : public ParserBase<Iterator,IPacket>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_UDP<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        Parse_UDP() {}
+        Parse_UDP(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+        static unsigned bytes() { return 8; }
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        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 ); }
+        Parse_16bit crc()             const { return Parse_16bit      (this->i() + 6 ); }
+
+    };
+
+    class UDPPacket
+        : public Packet, 
+          public Parse_UDP<Packet::iterator, UDPPacket>
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<UDPPacket>::ptr ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    private:
+        template <class Arg>
+        UDPPacket(Arg const & arg);
+
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+        virtual void v_dump(std::ostream & os) const;
+
+        friend class Packet;
+    };
+}}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include UDPPacket.cci"
+//#include "UDPPacket.ct"
+#include "UDPPacket.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/UDPPacket.test.cc b/Packets/UDPPacket.test.cc
new file mode 100644 (file)
index 0000000..afcb77d
--- /dev/null
@@ -0,0 +1,81 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "UDPPacket.test.hh"
+//#include "UDPPacket.test.ih"
+
+// Custom includes
+#include "UDPPacket.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::pkf;
+
+BOOST_AUTO_UNIT_TEST(udpPacket_parser)
+{
+    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_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       );    
+
+}
+
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/docstub.hh b/Packets/docstub.hh
new file mode 100644 (file)
index 0000000..3607b8f
--- /dev/null
@@ -0,0 +1,59 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_docstub_
+#define HH_docstub_ 1
+
+// Custom includes
+
+//#include "docstub.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace boost {
+
+    struct noncopyable {};
+    template <class Derived> struct totally_ordered {};
+    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////////////////////////////////////////
+//#include "docstub.cci"
+//#include "docstub.ct"
+//#include "docstub.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/imgconvert.mak b/Packets/imgconvert.mak
new file mode 100644 (file)
index 0000000..baf1b0d
--- /dev/null
@@ -0,0 +1,179 @@
+
+PSTOPNG_DPI := 100
+
+CLEAN_FILE := $(shell pwd)/.clean
+clean := clean() {                                                                                 \
+       touch $(CLEAN_FILE);                                                                        \
+       for file in "$$@"; do                                                                       \
+               grep "^$$file"'$$' $(CLEAN_FILE) >/dev/null || echo $$file >>$(CLEAN_FILE);         \
+       done                                                                                        \
+}; clean
+
+cmd  := run() { tput bold; echo -e "--[ $$* ]"; tput sgr0; } && run
+do   := run() { tput bold; echo -e "--[ $$* ]"; tput sgr0; "$$@"; } && run
+eval := run() { tput bold; echo -e "--[ $$* ]"; tput sgr0; eval "$$@"; } && run
+
+Q := @
+
+%.rawtex: %.stxt
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "rest2latex $< >$@";                                                             \
+         rest2latex                                                                                \
+                 --language=de                                                                     \
+                 --documentclass=scrreprt                                                          \
+                 --documentoptions="10pt,a4paper,DIV10"                                            \
+                 --table-style=booktabs                                                            \
+                 --use-verbatim-when-possible                                                      \
+                 --use-latex-footnotes                                                             \
+                 --use-latex-toc                                                                   \
+                 --no-section-numbering                                                            \
+                 --stylesheet=default.sty                                                          \
+                 --exit-status=2                                                                   \
+                 $<                                                                                \
+             > $@ || (rm -f $@; exit 1)
+
+%.tex: %.rawtex
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "rawfilter $< >$@";                                                              \
+         sed -e 's/\.\(png\|gif\|jpg\)/.pdf/g'                                                     \
+              -e 's/\[htbp\]/\[tbp\]/g' $< >$@                                                             \
+            || (rm -f $@; exit 1)
+
+%.html: %.stxt
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "rest2html $< >$@";                                                                  \
+         up="`echo $< | sed -r -e 's,^[^/]*$$,,' -e 's,/[^/]+$$,/,' -e 's,[^/]+,..,g'`";               \
+         rest2html                                                                                     \
+               --language=de                                                                           \
+               --exit-status=2                                                                         \
+               --stylesheet-path="$${up}default.css"                                                   \
+               $<                                                                                      \
+             > $@ || (rm -f $@; exit 1)
+
+%.pdf: %.tex
+       $(Q)(                                                                                       \
+         dir="$$(dirname $<)";                                                                     \
+         up="echo $$dir | sed -e 's,[^/]\+,..,g";                                                  \
+         [ -n "$$dir" ] && dir="$$dir/";                                                           \
+         stem="$$(basename $*)";                                                                   \
+         tex="$$(basename $<)";                                                                    \
+         pdf="$$(basename $@)";                                                                    \
+         $(clean) $${dir}texput.log;                                                               \
+         cd "$$dir";                                                                               \
+         repeat=5;                                                                                 \
+         origfiles="$$(find $$stem.* ! \( -name $$pdf -o -name $$stem.log \)                       \
+                                           -maxdepth 0 -printf '%p-%TY%Tm%Td%TH%TM%TS\n')";        \
+         while [ $$repeat -gt 0 ]; do                                                              \
+            $(cmd) "pdflatex --interaction nonstopmode $$tex";                                     \
+            TEXINPUTS=.:$$up: pdflatex --interaction nonstopmode $$tex;                            \
+            pdfexit=$$?;                                                                           \
+            auxfiles=$$((echo $$origfiles | tr ' ' '\n';                                           \
+                         find $$stem.* ! \( -name $$pdf -o -name $$stem.log \)                     \
+                                            -maxdepth 0 -printf '%p-%TY%Tm%Td%TH%TM%TS\n')         \
+                       | sort | uniq -u | sed -e 's/-[0-9]*$$//' | sort -u );                      \
+            for f in $$auxfiles; do                                                                \
+                $(clean) $$dir$$f;                                                                 \
+            done;                                                                                  \
+            $(clean) $*.log $@;                                                                    \
+            [ $$pdfexit -ne 0 ] && exit $$pdfexit;                                                 \
+            newauxsum=`md5sum $$auxfiles | md5sum 2>/dev/null`;                                    \
+            [ "$$auxsum" = "$$newauxsum" ] && break;                                               \
+            auxsum="$$newauxsum";                                                                  \
+            repeat=$$[ $$repeat - 1 ];                                                             \
+         done;                                                                                     \
+       ) || (rm -f $@; exit 1)
+
+%.png: %.sxd
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "(openoffice) sxdtopng $<"; \
+         openoffice -invisible "macro:///Local.Conversion.ConvertDrawToPNG($(shell realpath $<))"
+
+%.pdf: %.sxd
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "(openoffice) sxdtopdf $<"; \
+         openoffice -invisible "macro:///Local.Conversion.ConvertDrawToPDF($(shell realpath $<))"
+
+%.pdf: %.sxc
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "(openoffice) sxctopdf $<"; \
+         openoffice -invisible "macro:///Local.Conversion.ConvertCalcToPDF($(shell realpath $<))"
+
+%.ps: %.pdf
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "pdftops $< >$@"; \
+         pdftops -eps -nocrop -noshrink -nocenter $< - | pstops - >$@ || (rm -f $@; exit 1)
+
+%.png: %.ps
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "pstopng $< >$@";                                                                    \
+         bb=$$(grep -i '^%%BoundingBox:' $< | head -1 | sed -e 's/^%%BoundingBox: *//i');              \
+         bbx=$${bb% *};                                                                                \
+         bbx=$${bbx##* };                                                                              \
+         bby=$${bb##* };                                                                               \
+         pngx=$$(dc -e "$$bbx $(PSTOPNG_DPI) * 8 * 75.45 / p");                                        \
+         pngy=$$(dc -e "$$bby $(PSTOPNG_DPI) * 8 * 75.45 / p");                                        \
+         pstopnm -xborder 0 -yborder 0 -portrait -nocrop -stdout -xsize $$pngx -ysize $$pngy $<        \
+             | pnmscale -reduce 8                                                                      \
+             | pnmtopng >$@                                                                            \
+         || (rm -f $@; exit 1)
+
+%.gif: %.png
+       $(Q)$(clean) $@
+       $(Q)$(cmd) "pngtogif $< >$@"
+       $(Q)pngtopnm $< | ppmquant 256 | ppmtogif >$@ || ( rm -f $@; exit 1)
+
+%.pdf: %.dot
+       $(Q)$(clean) $@
+       $(Q)$(eval) "dot -Tfig $< | fig2dev -L pdf -f Helvetica >$@" || ( rm -f $@; exit 1 )
+
+%.pdf: %.neato
+       $(Q)$(clean) $@
+       $(Q)$(eval) "neato -Tfig $< | fig2dev -L pdf -f Helvetica >$@" || ( rm -f $@; exit 1 )
+
+%.eps: %.dia
+       $(Q)$(clean) $@
+       $(Q)$(do) dia -t eps -e $@ $<
+
+%.pdf: %.eps
+       $(Q)$(clean) $@
+       $(Q)$(do) epstopdf --outfile=$@ $<
+
+%.d: %.stxt
+       $(Q)$(clean) $@
+       $(Q)                                                                                        \
+         $(cmd) "makedep $<";                                                                      \
+         base="$$(dirname $<)";                                                                    \
+         [ -n "$$base" ] && base="$${base}/";                                                      \
+         function scaninc {                                                                        \
+                 local includes;                                                                   \
+                 [ -r $$1 ] || return;                                                             \
+                 includes="$$(sed -n -e 's/^.. \+include:: *//' -e T -e p $$1)";                   \
+                 for include in $$includes; do                                                     \
+                         echo $$base$$include;                                                     \
+                         scaninc $$base$$include;                                                  \
+                 done                                                                              \
+         };                                                                                        \
+         includes="$$(scaninc $<)";                                                                \
+         figures="$$(sed -n -e "s,^.. \+figure:: *,$$base," -e T -e p $< $$includes)";             \
+                                                                                                   \
+         echo "$*_Includes := $$(echo $$includes)"                                          >$@;   \
+         echo "$*_Figures := $$(echo $$figures)"                                           >>$@;   \
+         echo "$*_PDFs := $$(echo $$figures | sed -e 's/\.\(gif\|png\|jpg\)/.pdf/g')"      >>$@;   \
+         echo '$@: Makefile $< $$($*_Includes)'                                            >>$@;   \
+         echo '$*.html: $< $$($*_Includes)'                                                >>$@;   \
+         echo '$*_html: $*.html $$($*_Figures)'                                            >>$@;   \
+         echo '$*.tex: $< $$($*_Includes)'                                                 >>$@;   \
+         echo '$*.pdf: $*.tex $$($*_PDFs) $(TEX_STYLE)'                                    >>$@
+
+###########################################################################
+
+clean:
+       $(Q)if [ -r $(CLEAN_FILE) ]; then \
+           $(cmd) "xargs rm -f <.clean && rm -f .clean"; \
+           xargs rm -f <$(CLEAN_FILE) && rm -f $(CLEAN_FILE); \
+       fi
+
+# Local Variables:
+# mode: makefile
+# makefile-backslash-column: 100
+# End:
diff --git a/Packets/main.test.cc b/Packets/main.test.cc
new file mode 100644 (file)
index 0000000..ead6517
--- /dev/null
@@ -0,0 +1,43 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+//#include "test.hh"
+//#include "test.ih"
+
+// Custom includes
+#define BOOST_AUTO_TEST_MAIN
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// End:
diff --git a/Packets/satcom.css b/Packets/satcom.css
new file mode 100644 (file)
index 0000000..5b3d1db
--- /dev/null
@@ -0,0 +1,310 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+       font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+       font-size: 90%;
+}
+H1 {
+       text-align: center;
+       font-size: 160%;
+}
+H2 {
+       font-size: 120%;
+}
+H3 {
+       font-size: 100%;
+}
+CAPTION { font-weight: bold }
+DIV.qindex {
+       width: 100%;
+       background-color: #eeeeff;
+       border: 1px solid #b0b0b0;
+       text-align: center;
+       margin: 2px;
+       padding: 2px;
+       line-height: 140%;
+}
+DIV.nav {
+       width: 100%;
+       background-color: #eeeeff;
+       border: 1px solid #b0b0b0;
+       text-align: center;
+       margin: 2px;
+       padding: 2px;
+       line-height: 140%;
+}
+DIV.navtab {
+       background-color: #eeeeff;
+       border: 1px solid #b0b0b0;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+TD.navtab {
+       font-size: 70%;
+}
+A.qindex {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D;
+}
+A.qindex:visited {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D
+}
+A.qindex:hover {
+       text-decoration: none;
+       background-color: #ddddff;
+}
+A.qindexHL {
+       text-decoration: none;
+       font-weight: bold;
+       background-color: #6666cc;
+       color: #ffffff;
+       border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+       text-decoration: none;
+       background-color: #6666cc;
+       color: #ffffff;
+}
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A.elRef { font-weight: bold }
+A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
+A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:link { font-weight: normal; color: #0000FF}
+A.codeRef:visited { font-weight: normal; color: #0000FF}
+A:hover { text-decoration: none; background-color: #f2f2ff }
+DL.el { margin-left: -1cm }
+.fragment {
+       font-family: Fixed, monospace;
+       font-size: 95%;
+}
+PRE.fragment {
+       border: 1px solid #CCCCCC;
+       background-color: #f5f5f5;
+       margin-top: 4px;
+       margin-bottom: 4px;
+       margin-left: 2px;
+       margin-right: 8px;
+       padding-left: 6px;
+       padding-right: 6px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+TD.md { background-color: #F4F4FB; font-weight: bold; }
+TD.mdPrefix {
+       background-color: #F4F4FB;
+       color: #606060;
+       font-size: 80%;
+}
+TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
+TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
+DIV.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       margin-bottom: 6px;
+       font-weight: bold;
+}
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
+BODY {
+       background: white;
+       color: black;
+       margin-right: 20px;
+       margin-left: 20px;
+}
+TD.indexkey {
+       background-color: #eeeeff;
+       font-weight: bold;
+       padding-right  : 10px;
+       padding-top    : 2px;
+       padding-left   : 10px;
+       padding-bottom : 2px;
+       margin-left    : 0px;
+       margin-right   : 0px;
+       margin-top     : 2px;
+       margin-bottom  : 2px;
+       border: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+       background-color: #eeeeff;
+       font-style: italic;
+       padding-right  : 10px;
+       padding-top    : 2px;
+       padding-left   : 10px;
+       padding-bottom : 2px;
+       margin-left    : 0px;
+       margin-right   : 0px;
+       margin-top     : 2px;
+       margin-bottom  : 2px;
+       border: 1px solid #CCCCCC;
+}
+TR.memlist {
+   background-color: #f0f0f0; 
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword       { color: #008000 }
+SPAN.keywordtype   { color: #604020 }
+SPAN.keywordflow   { color: #e08000 }
+SPAN.comment       { color: #800000 }
+SPAN.preprocessor  { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral   { color: #008080 }
+.mdTable {
+       border: 1px solid #868686;
+       background-color: #F4F4FB;
+        width: 100%;
+}
+.mdRow {
+       padding: 8px 10px;
+}
+.mdescLeft {
+       padding: 0px 8px 4px 8px;
+       font-size: 80%;
+       font-style: italic;
+       background-color: #FAFAFA;
+       border-top: 1px none #E0E0E0;
+       border-right: 1px none #E0E0E0;
+       border-bottom: 1px none #E0E0E0;
+       border-left: 1px none #E0E0E0;
+       margin: 0px;
+}
+.mdescRight {
+       padding: 0px 8px 4px 8px;
+       font-size: 80%;
+       font-style: italic;
+       background-color: #FAFAFA;
+       border-top: 1px none #E0E0E0;
+       border-right: 1px none #E0E0E0;
+       border-bottom: 1px none #E0E0E0;
+       border-left: 1px none #E0E0E0;
+       margin: 0px;
+}
+.memItemLeft {
+       padding: 1px 0px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: solid;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.memItemRight {
+       padding: 1px 8px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: solid;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.memTemplItemLeft {
+       padding: 1px 0px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: none;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.memTemplItemRight {
+       padding: 1px 8px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: none;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.memTemplParams {
+       padding: 1px 0px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: solid;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       color: #606060;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.search     { color: #003399;
+              font-weight: bold;
+}
+FORM.search {
+              margin-bottom: 0px;
+              margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+               color: #000080;
+               font-weight: normal;
+               background-color: #eeeeff;
+}
+TD.tiny      { font-size: 75%;
+}
+a {
+       color: #252E78;
+}
+a:visited {
+       color: #3D2185;
+}
+.dirtab { padding: 4px;
+          border-collapse: collapse;
+          border: 1px solid #b0b0b0;
+}
+TH.dirtab { background: #eeeeff;
+            font-weight: bold;
+}
+HR { height: 1px;
+     border: none;
+     border-top: 1px solid black;
+}
diff --git a/Packets/structure.dia b/Packets/structure.dia
new file mode 100644 (file)
index 0000000..a3efbe8
Binary files /dev/null and b/Packets/structure.dia differ
diff --git a/Packets/typeidvalue.cci b/Packets/typeidvalue.cci
new file mode 100644 (file)
index 0000000..26d8c4f
--- /dev/null
@@ -0,0 +1,78 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+//#include "typeidvalue.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ satcom::lib::TypeIdValue::TypeIdValue()
+    : value_(new ValueImpl<void>()) 
+{}
+
+prefix_ satcom::lib::TypeIdValue::TypeIdValue(TypeIdValue const & other)
+{
+    value_.reset(other.value_->clone());
+}
+
+prefix_ satcom::lib::TypeIdValue const &
+satcom::lib::TypeIdValue::operator=(TypeIdValue const & other)
+{
+    value_.reset(other.value_->clone());
+    return *this;
+}
+
+prefix_ bool satcom::lib::TypeIdValue::operator==(TypeIdValue const & other)
+    const
+{
+    return value_->id() == other.value_->id();
+}
+
+prefix_ bool satcom::lib::TypeIdValue::operator<(TypeIdValue const & other)
+    const
+{
+    return value_->id().before(other.value_->id());
+}
+
+prefix_ std::string satcom::lib::TypeIdValue::name()
+    const
+{
+    return std::string(value_->id().name());
+}
+
+prefix_ satcom::lib::TypeIdValue const satcom::lib::typeIdValue()
+{
+    return TypeIdValue();
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/typeidvalue.cti b/Packets/typeidvalue.cti
new file mode 100644 (file)
index 0000000..9c78ae1
--- /dev/null
@@ -0,0 +1,63 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "typeidvalue.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Type>
+prefix_ satcom::lib::TypeIdValue::TypeIdValue(Type *)
+    : value_(new ValueImpl<Type>()) 
+{}
+
+template <class Type>
+prefix_ std::type_info const & satcom::lib::TypeIdValue::ValueImpl<Type>::id()
+{
+    return typeid(Type);
+}
+
+template <class Type>
+prefix_ satcom::lib::TypeIdValue::Value *
+satcom::lib::TypeIdValue::ValueImpl<Type>::clone()
+{
+    return new ValueImpl<Type>();
+}
+
+template <class Type>
+prefix_ satcom::lib::TypeIdValue const satcom::lib::typeIdValue()
+{
+    return TypeIdValue(static_cast<Type*>(0));
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Packets/typeidvalue.hh b/Packets/typeidvalue.hh
new file mode 100644 (file)
index 0000000..425c14f
--- /dev/null
@@ -0,0 +1,103 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_typeidvalue_
+#define HH_typeidvalue_ 1
+
+// Custom includes
+#include <typeinfo>
+#include <string>
+#include <boost/scoped_ptr.hpp>
+#include <boost/operators.hpp>
+
+//#include "typeidvalue.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    /** \brief Wrapper to use types as key's in a map
+      */
+    class TypeIdValue : public boost::totally_ordered<TypeIdValue>
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        // my default constructor
+        // my copy constructor
+        // my copy assignment
+        // default destructor
+        // no conversion constructors
+
+        TypeIdValue();
+        TypeIdValue(TypeIdValue const & other);
+        TypeIdValue const & operator=(TypeIdValue const & other);
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        bool operator==(TypeIdValue const & other) const;
+        bool operator<(TypeIdValue const & other) const;
+
+        std::string name() const;
+
+    protected:
+
+    private:
+        template <class Type> TypeIdValue(Type *);
+
+        struct Value {
+            virtual std::type_info const & id() = 0;
+            virtual Value * clone() = 0;
+        };
+
+        template <class Type>
+        struct ValueImpl : public Value {
+            virtual std::type_info const & id();
+            virtual Value * clone();
+        };
+
+        boost::scoped_ptr<Value> value_;
+
+        template <class Type> friend TypeIdValue const typeIdValue();
+    };
+
+    TypeIdValue const typeIdValue();
+    
+    template <class Type>
+    TypeIdValue const typeIdValue();
+    
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "typeidvalue.cci"
+//#include "typeidvalue.ct"
+#include "typeidvalue.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/SConfig b/SConfig
new file mode 100644 (file)
index 0000000..1a99c31
--- /dev/null
+++ b/SConfig
@@ -0,0 +1,9 @@
+CXX              = "g++-3.4"
+
+BOOST_INCLUDES   = "/usr/local/include/boost-1_33_1"
+BOOST_TOOLSET    = "gcc"
+BOOST_LIBDIR     = "/usr/local/lib"
+
+STLPORT_INCLUDES = "/usr/local/include/stlport"
+STLPORT_LIB      = "stlport_gcc"
+STLPORT_LIBDIR   = "/usr/local/lib"
diff --git a/SConstruct b/SConstruct
new file mode 100644 (file)
index 0000000..77b5b02
--- /dev/null
@@ -0,0 +1,22 @@
+import sys, glob
+sys.path.append('satscons')
+import SatSCons
+
+###########################################################################
+
+SatSCons.UseBoost();
+SatSCons.UseSTLPort();
+SatSCons.UseDoxygen();
+env = SatSCons.MakeEnvironment();
+
+env.Append(
+   CPPPATH = [ '#' ],
+   LIBS = [ 'iberty' ]
+)
+
+Export('env')
+
+SConscript(glob.glob("*/SConscript"))
+
+SatSCons.StandardTargets(env)
+SatSCons.GlobalTargets(env)
diff --git a/Scheduler/SConscript b/Scheduler/SConscript
new file mode 100644 (file)
index 0000000..fc9284e
--- /dev/null
@@ -0,0 +1,10 @@
+Import('env')
+import SatSCons
+
+###########################################################################
+
+SatSCons.StandardTargets(env)
+SatSCons.Lib(env,
+             library = 'Scheduler',
+             sources = SatSCons.GlobSources(),
+             LIBS = [ 'Utils' ])
diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc
new file mode 100644 (file)
index 0000000..21885f2
--- /dev/null
@@ -0,0 +1,203 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// TODO: Implement signal handling
+// Here a basic concept of how to add signal support to the scheduler:
+//
+// Every signal to be reported by the scheduler will be asigned a
+// generic signal handler by the scheduler. This signal handler will
+// use longjmp (juck) to report this signal back to the scheduler
+// main-loop.
+//
+// To make this safe, the main-loop will look something like:
+//
+//     int signal = setjmp(jmpBuffer_);
+//     if (signal == 0) {
+//         // unblock all signals which are registered with the
+//         // scheduler
+//         // call epoll
+//         // block all relevant signals again
+//     }
+//   
+//     // now handle the event
+//
+// The signal handler is then simply defined as
+//
+//     static void Scheduler::sigHandler(int signal)
+//     {
+//         // make sure to restore the signal handler here if
+//         // necessary
+//         longjmp(Scheduler::instance().jmpBuffer_,signal);
+//     }
+//
+// You should use sigaction to register the signal handlers and define
+// a sa_mask so all Scheduler-registered signals are automatically
+// *blocked* whenever one of the signals is called (including the
+// called signal!). This ensures, that no two signals can be delivered
+// on top of each other. And of course any signal registered with the
+// scheduler must be blocked as soon as it is registered with the
+// scheduler.
+
+// TODO: Multithreading support
+// To support multithreading, the static member Scheduler::instance()
+// must return a thread-local value (that is Scheduler::instance()
+// must allocate one Scheduler instance per thread)
+
+// Definition of non-inline non-template functions
+
+#include "Scheduler.hh"
+//#include "Scheduler.ih"
+
+// Custom includes
+#include <errno.h>
+#include <sys/epoll.h>
+#include "Utils/Exception.hh"
+
+static const int EPollInitialSize = 16;
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ satcom::lib::Scheduler::Scheduler & satcom::lib::Scheduler::instance()
+{
+    static Scheduler instance;
+    return instance;
+}
+
+prefix_ satcom::lib::Scheduler::Scheduler()
+    : epollFd_(epoll_create(EPollInitialSize))
+{
+    if (epollFd_<0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::Scheduler::add(int fd, Callback const & cb, EventId eventMask)
+{
+    FdTable::iterator i (fdTable_.find(fd));
+    int action (EPOLL_CTL_MOD);
+    if (i == fdTable_.end()) {
+        action = EPOLL_CTL_ADD;
+        i = fdTable_.insert(std::make_pair(fd, EventSpec())).first;
+    }
+
+    if (eventMask & EV_READ)  i->second.cb_read = cb;
+    if (eventMask & EV_PRIO)  i->second.cb_prio = cb;
+    if (eventMask & EV_WRITE) i->second.cb_write = cb;
+    if (eventMask & EV_HUP)   i->second.cb_hup = cb;
+    if (eventMask & EV_ERR)   i->second.cb_err = cb;
+
+    epoll_event ev;
+    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 satcom::lib::Scheduler::remove(int fd, EventId eventMask)
+{
+    FdTable::iterator i (fdTable_.find(fd));
+    if (i == fdTable_.end()) 
+        return;
+
+    if (eventMask & EV_READ)  i->second.cb_read = 0;
+    if (eventMask & EV_PRIO)  i->second.cb_prio = 0;
+    if (eventMask & EV_WRITE) i->second.cb_write = 0;
+    if (eventMask & EV_HUP)   i->second.cb_hup = 0;
+    if (eventMask & EV_ERR)   i->second.cb_err = 0;
+
+    epoll_event ev;
+    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;
+        fdTable_.erase(i);
+    }
+
+    if (epoll_ctl(epollFd_, action, fd, &ev)<0)
+        throw SystemException(errno);
+}
+
+prefix_ int satcom::lib::Scheduler::EventSpec::epollMask()
+    const
+{
+    int mask (0);
+    if (cb_read)  mask |= EPOLLIN;
+    if (cb_prio)  mask |= EPOLLPRI;
+    if (cb_write) mask |= EPOLLOUT;
+    if (cb_hup)   mask |= EPOLLHUP;
+    if (cb_err)   mask |= EPOLLERR;
+    return mask;
+}
+
+prefix_ void satcom::lib::Scheduler::process()
+{
+    terminate_ = false;
+    while (! terminate_) {
+        struct epoll_event ev;
+        int events = epoll_wait(epollFd_, &ev, 1, 1000);
+        if (events<0)
+            // Hmm ... man epoll says, it will NOT return with EINTR ??
+            throw SystemException(errno);
+        if (events==0)
+            continue;
+        
+        FdTable::iterator i = fdTable_.find(ev.data.fd);
+        BOOST_ASSERT (i != fdTable_.end() );
+        EventSpec const & spec (i->second); 
+
+        if (ev.events & EPOLLIN) {
+            BOOST_ASSERT(spec.cb_read); 
+            spec.cb_read(ev.data.fd, EV_READ);
+        }
+        else if (ev.events & EPOLLPRI) {
+            BOOST_ASSERT(spec.cb_prio);
+            spec.cb_prio (ev.data.fd, EV_PRIO);
+        }
+        else if (ev.events & EPOLLOUT) {
+            BOOST_ASSERT(spec.cb_write);
+            spec.cb_write(ev.data.fd, EV_WRITE);
+        }
+
+        else if (ev.events & EPOLLHUP) {
+            BOOST_ASSERT(spec.cb_hup);
+            spec.cb_hup(ev.data.fd, EV_HUP);
+        }
+        else if (ev.events & EPOLLERR) {
+            BOOST_ASSERT(spec.cb_err);
+            spec.cb_err(ev.data.fd, EV_ERR);
+        }
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Scheduler/Scheduler.cci b/Scheduler/Scheduler.cci
new file mode 100644 (file)
index 0000000..f34286e
--- /dev/null
@@ -0,0 +1,44 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+//#include "Scheduler.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ void satcom::lib::Scheduler::terminate()
+{
+    terminate_ = true;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Scheduler/Scheduler.ct b/Scheduler/Scheduler.ct
new file mode 100644 (file)
index 0000000..05afa48
--- /dev/null
@@ -0,0 +1,39 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+//#include "Scheduler.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Scheduler/Scheduler.cti b/Scheduler/Scheduler.cti
new file mode 100644 (file)
index 0000000..7ef1148
--- /dev/null
@@ -0,0 +1,55 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "Scheduler.ih"
+
+// Custom includes
+#include <boost/bind.hpp>
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Handle>
+prefix_ void satcom::lib::Scheduler::add(Handle const & handle,
+                                         typename GenericCallback<Handle>::Callback const & cb,
+                                         EventId eventMask)
+{
+    add(retrieve_filehandle(handle),boost::bind(cb,handle,_2),eventMask);
+}
+
+template <class Handle>
+prefix_ void satcom::lib::Scheduler::remove(Handle const & handle, EventId eventMask)
+{
+    // retrieve_filehandle is found via ADL
+    remove(retrieve_filehandle(handle),eventMask);
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Scheduler/Scheduler.hh b/Scheduler/Scheduler.hh
new file mode 100644 (file)
index 0000000..e731db4
--- /dev/null
@@ -0,0 +1,128 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_Scheduler_
+#define HH_Scheduler_ 1
+
+// Custom includes
+#include <map>
+#include <boost/function.hpp>
+#include <boost/utility.hpp>
+#include <boost/call_traits.hpp>
+
+//#include "scheduler.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    /** \brief Singleton class to manage the event loop
+
+        This class manages a single select() type event loop. A
+        customer of this class may register any number of file
+        descriptiors with this class and pass callback functions to be
+        called on input, output or error. This functions are specified
+        using boost::function objects
+      */
+    class Scheduler
+        : boost::noncopyable
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        enum EventId { EV_NONE=0, 
+                       EV_READ=1, EV_PRIO=2, EV_WRITE=4, EV_HUP=8, EV_ERR=16, 
+                       EV_ALL=31 };
+
+        template <class Handle>
+        struct GenericCallback {
+            typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
+                                          EventId) > Callback;
+        };
+        typedef GenericCallback<int>::Callback Callback;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        // private default constructor
+        // no copy constructor
+        // no copy assignment
+        // default destructor
+        // no conversion constructors
+
+        static Scheduler & instance();
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        void add(int fd, Callback const & cb, EventId eventMask = EV_ALL);
+        void remove(int fd, EventId eventMask = EV_ALL);
+
+        template <class Handle>
+        void add(Handle const & handle, 
+                 typename GenericCallback<Handle>::Callback const & cb,
+                 EventId eventMask = EV_ALL);
+        template <class Handle>
+        void remove(Handle const & handle, EventId eventMask = EV_ALL);
+
+        void process();
+
+        void terminate();
+
+    protected:
+
+    private:
+        Scheduler();
+
+        struct EventSpec 
+        {
+            Callback cb_read;
+            Callback cb_prio;
+            Callback cb_write;
+            Callback cb_hup;
+            Callback cb_err;
+
+            int epollMask() const;
+        };
+        
+        typedef std::map<int,EventSpec> FdTable;
+
+        FdTable fdTable_;
+        int epollFd_;
+        bool terminate_;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "Scheduler.cci"
+#include "Scheduler.ct"
+#include "Scheduler.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Scheduler/Scheduler.test.cc b/Scheduler/Scheduler.test.cc
new file mode 100644 (file)
index 0000000..fb5ae35
--- /dev/null
@@ -0,0 +1,249 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "scheduler.test.hh"
+//#include "scheduler.test.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <string.h>
+#include <iostream>
+
+#include "Scheduler.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::lib;
+
+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;
+    }
+
+    void fail(char const * fn)
+    {
+        error(fn,"server: ");
+        _exit(1);
+    }
+
+    void server()
+    {
+        int sock = socket(PF_UNIX,SOCK_STREAM,0);
+        if (sock<0) fail("socket");
+        struct sockaddr_un sun;
+        memset(&sun,0,sizeof(sun));
+        sun.sun_family = AF_UNIX;
+        strcpy(sun.sun_path,SOCK_PATH);
+        if (bind(sock,(struct sockaddr*)&sun,sizeof(sun))<0) fail("bind");
+        if (listen(sock,1)<0) fail("listen");
+        int conn = accept(sock,0,0);
+        if (conn < 0) fail("accept");
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        if (write(conn,"READ",4)<0) fail("write");
+        char buffer[1024];
+        int size =  read(conn,buffer,1024);
+        if (size<0) fail("read");
+        if (size == 5) {
+            buffer[5] = 0;
+            if (strcmp(buffer,"WRITE")==0) {
+                if (write(conn,"OK",2)<0) fail("write");
+            } else
+                if (write(conn,"FAIL",4)<0) fail("write");
+        } else
+            if (write(conn,"FAIL",4)<0) fail("write");
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        close(conn);
+        close(sock);
+    }
+
+    int start_server()
+    {
+        unlink(SOCK_PATH);
+        int pid = fork();
+        if (pid == 0) {
+            server();
+            _exit(0);
+        }
+        if (pid < 0) {
+            error("fork");
+            return 0;
+        }
+            
+        sleep(1); // Wait for the server socket to be opened
+        return pid;
+    }
+
+    bool stop_server(int pid)
+    {
+        sleep(1); // Wait for the server to terminate
+        if (kill(pid,SIGTERM)<0) {
+            error("kill");
+            return false;
+        }
+        int status = 0;
+        if (waitpid(pid,&status,0)<0) {
+            error("waitpid");
+            return false;
+        }
+        unlink(SOCK_PATH);
+        if (WIFSIGNALED(status)) {
+            std::cerr << "\nserver terminated with signal " << WTERMSIG(status) << std::endl;
+            return false;
+        }
+        if (WEXITSTATUS(status)!=0) {
+            std::cerr << "\nserver terminated with exit status " << WEXITSTATUS(status) << std::endl;
+            return false;
+        }
+        return true;
+    }
+
+    char buffer[1024];
+    int size;
+    int event;
+
+    void callback(int fd, Scheduler::EventId ev)
+    {
+        event = ev;
+        switch (event) {
+        case Scheduler::EV_READ:
+            size = recv(fd,buffer,1024,0);
+            break;
+        case Scheduler::EV_PRIO:
+            size = recv(fd,buffer,1024,MSG_OOB);
+            Scheduler::instance().terminate();
+            break;
+        case Scheduler::EV_WRITE:
+            size = write(fd,buffer,size);
+            Scheduler::instance().terminate();
+            break;
+        case Scheduler::EV_HUP:
+        case Scheduler::EV_ERR:
+        case Scheduler::EV_NONE:
+        case Scheduler::EV_ALL:
+            ;
+        }
+        Scheduler::instance().terminate();
+    }
+     
+    struct HandleWrapper
+    {
+        HandleWrapper(int fd,std::string const & tag) : fd_(fd), tag_(tag) {}
+        int fd_;
+        std::string tag_;
+    };
+
+    int retrieve_filehandle(HandleWrapper const & handle)
+    {
+        return handle.fd_;
+    }
+
+    void handleCallback(HandleWrapper const & handle, Scheduler::EventId event)
+    {
+        if (handle.tag_ != "TheTag")
+            return;
+        callback(handle.fd_,event);
+    }
+}
+
+BOOST_AUTO_UNIT_TEST(scheduler)
+{
+    int pid = start_server();
+    BOOST_REQUIRE (pid);
+
+    int sock = socket(PF_UNIX,SOCK_STREAM,0);
+    if (sock<0) {
+        error("socket");
+        BOOST_FAIL("socket");
+    }
+    struct sockaddr_un sun;
+    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_NO_THROW( Scheduler::instance() );
+
+    BOOST_CHECK_NO_THROW( Scheduler::instance().add(sock,&callback,Scheduler::EV_READ) );
+    event = Scheduler::EV_NONE;
+    BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
+    BOOST_CHECK_EQUAL( event, Scheduler::EV_READ );
+    BOOST_REQUIRE_EQUAL( size, 4 );
+    buffer[size]=0;
+    BOOST_CHECK_EQUAL( buffer, "READ" );
+
+    HandleWrapper handle(sock,"TheTag");
+    BOOST_CHECK_NO_THROW( Scheduler::instance().add(handle,&handleCallback,Scheduler::EV_WRITE) );
+    strcpy(buffer,"WRITE");
+    size=5;
+    event = Scheduler::EV_NONE;
+    BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
+    BOOST_CHECK_EQUAL( event, Scheduler::EV_WRITE );
+
+    BOOST_CHECK_NO_THROW( Scheduler::instance().remove(handle,Scheduler::EV_WRITE) );
+    event = Scheduler::EV_NONE;
+    BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
+    BOOST_CHECK_EQUAL( event, Scheduler::EV_READ );
+    BOOST_REQUIRE_EQUAL( size, 2 );
+    buffer[size]=0;
+    BOOST_CHECK_EQUAL( buffer, "OK" );
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    close(sock);
+
+    BOOST_CHECK (stop_server(pid));
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Scheduler/main.test.cc b/Scheduler/main.test.cc
new file mode 100644 (file)
index 0000000..fd4c97a
--- /dev/null
@@ -0,0 +1,43 @@
+// $Id: main.test.cc 32 2006-03-23 16:24:56Z sbund $
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+//#include "test.hh"
+//#include "test.ih"
+
+// Custom includes
+#define BOOST_AUTO_TEST_MAIN
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// End:
diff --git a/Socket/AddressingPolicy.hh b/Socket/AddressingPolicy.hh
new file mode 100644 (file)
index 0000000..b13ac1d
--- /dev/null
@@ -0,0 +1,51 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_AddressingPolicy_
+#define HH_AddressingPolicy_ 1
+
+// Custom includes
+#include "SocketPolicy.hh"
+
+//#include "AddressingPolicy.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    struct NoAddressingPolicy : public AddressingPolicyBase
+    {};
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "AddressingPolicy.cci"
+//#include "AddressingPolicy.ct"
+//#include "AddressingPolicy.cti"
+//#include "AddressingPolicy.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/BSDSocketProtocol.cc b/Socket/BSDSocketProtocol.cc
new file mode 100644 (file)
index 0000000..1176861
--- /dev/null
@@ -0,0 +1,98 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "BSDSocketProtocol.hh"
+//#include "BSDSocketProtocol.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include "SocketHandle.hh"
+
+//#include "BSDSocketProtocol.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ std::pair<bool,unsigned> satcom::lib::BSDSocketProtocol::linger()
+    const
+{
+    struct linger ling;
+    socklen_t len = sizeof(ling);
+    ::memset(&ling,sizeof(ling),0);
+    if (::getsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,&len) < 0)
+        throw SystemException(errno);
+    return std::make_pair(ling.l_onoff, ling.l_linger);
+}
+
+prefix_ void satcom::lib::BSDSocketProtocol::linger(bool enable, unsigned timeout)
+    const
+{
+    struct linger ling;
+    ling.l_onoff = enable;
+    ling.l_linger = timeout;
+    if (::setsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ struct timeval satcom::lib::BSDSocketProtocol::timestamp()
+    const
+{
+    // TODO: Check, why this fails with ENOFILE (!!!!) at least when
+    // called from a tcp socket. Further investigation necessary ...
+    struct timeval tv;
+    if (::ioctl(body().fd(), SIOCGSTAMP, &tv) < 0)
+        throw SystemException(errno);
+    return tv;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+prefix_ bool satcom::lib::AddressableBSDSocketProtocol::reuseaddr()
+    const
+{
+    int value;
+    socklen_t len (sizeof(value));
+    if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0)
+        throw SystemException(errno);
+    return value;
+}
+
+prefix_ void satcom::lib::AddressableBSDSocketProtocol::reuseaddr(bool value)
+    const
+{
+    int ivalue (value);
+    if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0)
+        throw SystemException(errno);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "BSDSocketProtocol.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/BSDSocketProtocol.hh b/Socket/BSDSocketProtocol.hh
new file mode 100644 (file)
index 0000000..3d35599
--- /dev/null
@@ -0,0 +1,68 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_BSDSocketProtocol_
+#define HH_BSDSocketProtocol_ 1
+
+// Custom includes
+#include <sys/time.h>
+#include "SocketProtocol.hh"
+
+//#include "BSDSocketProtocol.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    class BSDSocketProtocol
+        : public virtual SocketProtocol
+    {
+    public:
+        std::pair<bool,unsigned> linger() const;
+        void linger(bool enable, unsigned timeout) const;
+
+        struct timeval timestamp() const;
+    };
+
+    class AddressableBSDSocketProtocol
+        : public virtual SocketProtocol
+    {
+    public:
+        bool reuseaddr() const;
+        void reuseaddr(bool value) const;
+    };
+
+}}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "BSDSocketProtocol.cci"
+//#include "BSDSocketProtocol.ct"
+//#include "BSDSocketProtocol.cti"
+//#include "BSDSocketProtocol.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/BufferingPolicy.cc b/Socket/BufferingPolicy.cc
new file mode 100644 (file)
index 0000000..e1c3171
--- /dev/null
@@ -0,0 +1,81 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "BufferingPolicy.hh"
+//#include "BufferingPolicy.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include "Utils/Exception.hh"
+
+//#include "BufferingPolicy.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ unsigned satcom::lib::SocketBufferingPolicy::rcvbuf(FileHandle handle)
+{
+    unsigned size;
+    socklen_t len (sizeof(size));
+    if (::getsockopt(handle.fd(),SOL_SOCKET,SO_RCVBUF,&size,&len) < 0)
+        throw SystemException(errno);
+    // Linux doubles the bufer size on setting the RCVBUF to cater for internal
+    // headers. We fix this up here .. (see lkml FAQ)
+    return size/2;
+}
+
+prefix_ void satcom::lib::SocketBufferingPolicy::rcvbuf(FileHandle handle, unsigned size)
+{
+    if (::setsockopt(handle.fd(),SOL_SOCKET,SO_RCVBUF,&size,sizeof(size)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ unsigned satcom::lib::SocketBufferingPolicy::sndbuf(FileHandle handle)
+{
+    unsigned size;
+    socklen_t len (sizeof(size));
+    if (::getsockopt(handle.fd(),SOL_SOCKET,SO_SNDBUF,&size,&len) < 0)
+        throw SystemException(errno);
+    // 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 satcom::lib::SocketBufferingPolicy::sndbuf(FileHandle handle, unsigned size)
+{
+    if (::setsockopt(handle.fd(),SOL_SOCKET,SO_SNDBUF,&size,sizeof(size)) < 0)
+        throw SystemException(errno);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "BufferingPolicy.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/BufferingPolicy.hh b/Socket/BufferingPolicy.hh
new file mode 100644 (file)
index 0000000..9dccd88
--- /dev/null
@@ -0,0 +1,59 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_BufferingPolicy_
+#define HH_BufferingPolicy_ 1
+
+// Custom includes
+#include "FileHandle.hh"
+#include "SocketPolicy.hh"
+
+//#include "BufferingPolicy.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    // TODO: Should this be dependent on Read / WritePolicy ?
+    struct SocketBufferingPolicy : public BufferingPolicyBase
+    {
+        static unsigned rcvbuf(FileHandle handle);
+        static void rcvbuf(FileHandle handle, unsigned size);
+
+        static unsigned sndbuf(FileHandle handle);
+        static void sndbuf(FileHandle handle, unsigned size);
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "BufferingPolicy.cci"
+//#include "BufferingPolicy.ct"
+//#include "BufferingPolicy.cti"
+//#include "BufferingPolicy.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ClientSocketHandle.ct b/Socket/ClientSocketHandle.ct
new file mode 100644 (file)
index 0000000..1e7fa7b
--- /dev/null
@@ -0,0 +1,112 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+//#include "ClientSocketHandle.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class Policy>
+prefix_ std::string satcom::lib::ClientSocketHandle<Policy>::read()
+{
+    std::string rv;
+    this->read(rv);
+    return rv;
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::read(std::string & buffer)
+{
+    unsigned nread = available();
+    // 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);
+    if (rv < nread)
+        buffer.erase(buffer.begin()+rv,buffer.end());
+}
+
+template <class Policy>
+prefix_ std::pair<std::string, typename Policy::AddressingPolicy::Address>
+satcom::lib::ClientSocketHandle<Policy>::readfrom()
+{
+    std::string rv;
+    typename Policy::AddressingPolicy::Address addr;
+    this->readfrom(rv,addr);
+    return std::make_pair(rv,addr);
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::
+readfrom(std::string & buffer, typename Policy::AddressingPolicy::Address & from)
+{
+    unsigned nread = available();
+    // FIXME: This is not necessary correct and more or less a hack ...
+    buffer.assign(nread,0);
+    unsigned rv = this->readfrom(const_cast<char *>(buffer.data()), nread, from);
+    if (rv < nread)
+        buffer.erase(buffer.begin()+rv,buffer.end());
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::write(std::string const & data)
+{
+    unsigned written = this->write(data.data(),data.size());
+    if (written == 0)
+        throw SystemException(EPIPE);
+    // This implementation ensures, we only call blocking() when
+    // necessary (since it incurs a system call overhead ...)
+    if (written < data.size() && this->blocking())
+        // We need to enforce in the WritePolicy implementation, that
+        // 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); 
+            if (n == 0)
+                throw SystemException(EPIPE);
+            written += n;
+        }
+    return written;
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::available()
+{
+    unsigned nread = this->protocol().available();
+    if (nread == 0 && this->blocking()) {
+            this->waitReadable();
+            nread = this->protocol().available();
+    }
+    return nread;
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti
new file mode 100644 (file)
index 0000000..eec7cf7
--- /dev/null
@@ -0,0 +1,222 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "ClientSocketHandle.ih"
+
+// Custom includes
+#include <typeinfo>
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Policy>
+template <class OtherPolicy>
+prefix_ satcom::lib::ClientSocketHandle<Policy>::
+ClientSocketHandle(ClientSocketHandle<OtherPolicy> other,
+                   typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type *)
+    : SocketHandle<Policy>(other,true)
+{}
+
+template <class Policy>
+prefix_ satcom::lib::ClientSocketHandle<Policy>::ClientSocketHandle(FileHandle other,
+                                                                    bool isChecked)
+    : SocketHandle<Policy>(other, isChecked)
+{}
+
+template <class Policy>
+prefix_  satcom::lib::ClientSocketHandle<Policy>::
+ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol, int fd)
+    : SocketHandle<Policy>(protocol,false)
+{
+    this->body().fd(fd);
+}
+
+template <class Policy>
+template <class OtherPolicy>
+prefix_ typename satcom::lib::SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const &
+satcom::lib::ClientSocketHandle<Policy>::operator=(ClientSocketHandle<OtherPolicy> other)
+{
+    assign(other);
+    return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// reading and writing
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::read(char * buffer,
+                                                                     unsigned size)
+{
+    return Policy::ReadPolicy::read(*this, buffer, size);
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::
+readfrom(char * buffer, unsigned size, typename Policy::AddressingPolicy::Address & from)
+{
+    return Policy::ReadPolicy::readfrom(*this, buffer, size, from);
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::write(char const * buffer,
+                                                                unsigned size)
+{
+    return Policy::WritePolicy::write(*this, buffer, size);
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::
+writeto(typename boost::call_traits<typename Policy::AddressingPolicy::Address>::param_type addr,
+        std::string const & data)
+{
+    return this->writeto(addr, data.data(), data.size());
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::
+writeto(typename boost::call_traits<typename Policy::AddressingPolicy::Address>::param_type addr,
+        char const * buffer, unsigned size)
+{
+    return Policy::WritePolicy::writeto(*this, addr, buffer, size);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// addressing
+
+template <class Policy>
+prefix_ typename Policy::AddressingPolicy::Address
+satcom::lib::ClientSocketHandle<Policy>::peer()
+{
+    typename Policy::AddressingPolicy::Address addr;
+    this->peer(addr);
+    return addr;
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::
+peer(typename Policy::AddressingPolicy::Address & addr)
+{
+    Policy::AddressingPolicy::peer(*this,addr);
+}
+
+template <class Policy>
+prefix_ typename Policy::AddressingPolicy::Address
+satcom::lib::ClientSocketHandle<Policy>::local()
+{
+    typename Policy::AddressingPolicy::Address addr;
+    this->local(addr);
+    return addr;
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::
+local(typename Policy::AddressingPolicy::Address & addr)
+{
+    Policy::AddressingPolicy::local(*this,addr);
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::connect(AddressParam addr)
+{
+    Policy::AddressingPolicy::connect(*this,addr);
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::
+bind(typename boost::call_traits<typename Policy::AddressingPolicy::Address>::param_type addr)
+{
+    Policy::AddressingPolicy::bind(*this,addr);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Buffering
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::rcvbuf()
+{
+    return Policy::BufferingPolicy::rcvbuf(*this);
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::rcvbuf(unsigned size)
+{
+    Policy::BufferingPolicy::rcvbuf(*this,size);
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::sndbuf()
+{
+    return Policy::BufferingPolicy::sndbuf(*this);
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::sndbuf(unsigned size)
+{
+    Policy::BufferingPolicy::sndbuf(*this,size);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+template <class Policy>
+prefix_ satcom::lib::ClientSocketHandle<Policy>
+satcom::lib::ClientSocketHandle<Policy>::cast_static(FileHandle handle)
+{
+    return ClientSocketHandle(handle, true);
+}
+
+template <class Policy>
+prefix_ satcom::lib::ClientSocketHandle<Policy>
+satcom::lib::ClientSocketHandle<Policy>::cast_dynamic(FileHandle handle)
+{
+    SocketHandle<Policy> h (SocketHandle<Policy>::cast_dynamic(handle));
+    if (static_cast<SocketBody&>(FileHandle::body(h)).isServer())
+        throw std::bad_cast();
+    return cast_static(handle);
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ClientSocketHandle<Policy>::state(SocketStateMap & map, unsigned lod)
+{
+    map["handle"] = prettyName(typeid(*this));
+    this->body().state(map,lod);
+}
+
+template <class Policy>
+prefix_ std::string satcom::lib::ClientSocketHandle<Policy>::dumpState(unsigned lod)
+{
+    SocketStateMap map;
+    state(map,lod);
+    return detail::dumpState(map);
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ClientSocketHandle.hh b/Socket/ClientSocketHandle.hh
new file mode 100644 (file)
index 0000000..0e670ab
--- /dev/null
@@ -0,0 +1,156 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// TODO: Move all not template-parameter dependent code into a
+// non-template base class
+
+#ifndef HH_ClientSocketHandle_
+#define HH_ClientSocketHandle_ 1
+
+// Custom includes
+#include <boost/call_traits.hpp>
+#include "SocketHandle.hh"
+
+//#include "ClientSocketHandle.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    template <class Policy> class ServerSocketHandle;
+
+    /** \brief
+      */
+    template <class Policy>
+    class ClientSocketHandle
+        : public SocketHandle<Policy>
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef typename Policy::AddressingPolicy::Address Address;
+        typedef typename boost::call_traits<Address>::param_type AddressParam;
+        typedef ServerSocketHandle<Policy> ServerSocketHandle;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        // no default constructor
+        // default copy constructor
+        // default copy assignment
+        // default destructor
+
+        // conversion constructors
+        template <class OtherPolicy>
+        ClientSocketHandle(ClientSocketHandle<OtherPolicy> other,
+                           typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type * = 0);
+
+        template <class OtherPolicy>
+        typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const & 
+        operator=(ClientSocketHandle<OtherPolicy> other);
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name reading and writing
+        ///@{
+
+        // read from socket (connected or unconnected)
+        std::string  read         ();
+        void         read         (std::string & buffer);
+        unsigned     read         (char * buffer, unsigned size);
+
+        // read from unconnected socket returning peer address
+        std::pair<std::string, Address> 
+                     readfrom     ();
+        void         readfrom     (std::string & buffer, Address & from);
+        unsigned     readfrom     (char * buffer, unsigned size, Address & from);
+
+        // write to connected socket
+        unsigned     write        (std::string const & data);
+        unsigned     write        (char const * buffer, unsigned size);
+
+        // write to unconnected socket
+        unsigned     writeto      (AddressParam addr, std::string const & data);
+        unsigned     writeto      (AddressParam addr, char const * buffer, unsigned size);
+
+        ///@}
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Addressing
+        ///@{
+
+        void         connect      (AddressParam addr);
+        void         bind         (AddressParam addr);
+
+        Address      peer         ();
+        void         peer         (Address & addr);
+        Address      local        ();
+        void         local        (Address & addr);
+
+        ///@}
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Buffering
+        ///@{
+        
+        unsigned     rcvbuf      ();
+        void         rcvbuf      (unsigned size);        
+        unsigned     sndbuf      ();
+        void         sndbuf      (unsigned size);
+        
+        ///@}
+        
+        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);
+
+    protected:
+        ClientSocketHandle(FileHandle other, bool isChecked);
+        explicit ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol,
+                                    int fd = -1);
+
+    private:
+        unsigned available();
+
+        friend class satcom::lib::ServerSocketHandle<Policy>;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ClientSocketHandle.cci"
+#include "ClientSocketHandle.ct"
+#include "ClientSocketHandle.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ClientSocketHandle.test.cc b/Socket/ClientSocketHandle.test.cc
new file mode 100644 (file)
index 0000000..e82c57d
--- /dev/null
@@ -0,0 +1,139 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ClientSocketHandle.test.hh"
+//#include "ClientSocketHandle.test.ih"
+
+// Custom includes
+#include "SocketPolicy.test.hh"
+#include "SocketProtocol.test.hh"
+#include "ClientSocketHandle.hh"
+#include "AddressingPolicy.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+
+    namespace sl = satcom::lib;
+
+    class MySocketHandle
+        : public sl::ClientSocketHandle<sl::test::SomeProtocol::Policy>
+    {
+    public:
+        MySocketHandle()
+            : sl::ClientSocketHandle<sl::test::SomeProtocol::Policy>(
+                std::auto_ptr<sl::SocketProtocol>(new sl::test::SomeProtocol()))
+            {}
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(clientSocketHandle)
+{
+    BOOST_CHECKPOINT("Constructing socket handle");
+    MySocketHandle myh;
+
+    // conversion to other socket handles
+    {
+        typedef sl::MakeSocketPolicy<
+            sl::test::SomeFramingPolicy,
+            sl::test::SomeReadPolicy,
+            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 = 
+            sl::static_socket_cast<SomeSocketHandle>(osh);
+        BOOST_CHECK_NO_THROW( sl::dynamic_socket_cast<SomeSocketHandle>(osh) );
+        typedef sl::ClientSocketHandle<sl::MakeSocketPolicy<
+            OtherSocketPolicy,
+            sl::NoAddressingPolicy
+            >::policy> SomeOtherSocketHandle;
+        BOOST_CHECK_THROW( sl::dynamic_socket_cast<SomeOtherSocketHandle>(osh),
+                           std::bad_cast );
+    }
+
+    // reading and writing
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.read(), "TEST-READ" ) );
+    {
+        std::string buf("FOO-BAR");
+        BOOST_CHECK_NO_THROW( myh.read(buf) );
+        BOOST_CHECK_EQUAL( buf, "TEST-READ" );
+    }
+    {
+        char buf[11];
+        ::strcpy(buf,"0123456789");
+        BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.read(buf,10), 9u ) );
+        BOOST_CHECK_EQUAL( buf, "TEST-READ9" );
+    }
+
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.readfrom().first, "TEST-READ" ) );
+    {
+        std::string buf("FOO-BAR");
+        unsigned addr;
+        BOOST_CHECK_NO_THROW( myh.readfrom(buf,addr) );
+        BOOST_CHECK_EQUAL( buf, "TEST-READ" );
+    }
+    {
+        char buf[11];
+        unsigned addr;
+        ::strcpy(buf,"0123456789");
+        BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.readfrom(buf,10,addr), 9u ) );
+        BOOST_CHECK_EQUAL( buf, "TEST-READ9" );
+    }
+
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.write("TEST-WRITE"), 10u ) );
+    BOOST_CHECK_THROW( myh.write("TEST"),satcom::lib::SystemException );
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.write("TEST-WRITE9",10), 10u ) );
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.writeto(0,"TEST-WRITE"), 10u ) );
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.writeto(0,"TEST-WRITE9",10), 10u ) );
+
+    BOOST_CHECK_NO_THROW( myh.connect(0) );
+    BOOST_CHECK_NO_THROW( myh.bind(0) );
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.peer(), 1u ) );
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.local(), 2u ) );
+
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.rcvbuf(), 0u ) );
+    BOOST_CHECK_NO_THROW( myh.rcvbuf(1) );
+    BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.sndbuf(), 0u ) );
+    BOOST_CHECK_NO_THROW( myh.sndbuf(1) );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/CommunicationPolicy.cc b/Socket/CommunicationPolicy.cc
new file mode 100644 (file)
index 0000000..8523966
--- /dev/null
@@ -0,0 +1,74 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "CommunicationPolicy.hh"
+//#include "CommunicationPolicy.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include "Utils/Exception.hh"
+#include "ServerSocketHandle.hh"
+
+//#include "CommunicationPolicy.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void satcom::lib::ConnectedCommunicationPolicy::listen(FileHandle handle,
+                                                               unsigned backlog)
+{
+    ::listen(handle.fd(),backlog);
+}
+
+prefix_ int satcom::lib::ConnectedCommunicationPolicy::do_accept(FileHandle handle,
+                                                                 struct sockaddr * addr,
+                                                                 unsigned len)
+{
+    int rv = -1;
+    do {
+        rv = ::accept(handle.fd(),addr,&len);
+        if (rv < 0)
+            switch (errno) {
+            case EWOULDBLOCK:
+                return -1;
+                break;
+            case EINTR:
+                break;
+            default:
+                throw SystemException(errno);
+            }
+    } while (rv<0);
+    return rv;
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "CommunicationPolicy.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/CommunicationPolicy.cti b/Socket/CommunicationPolicy.cti
new file mode 100644 (file)
index 0000000..f3be50d
--- /dev/null
@@ -0,0 +1,48 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "CommunicationPolicy.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Policy>
+prefix_ int satcom::lib::ConnectedCommunicationPolicy::
+accept(ServerSocketHandle<Policy> handle,
+       typename ServerSocketHandle<Policy>::Address & address,
+       typename IfAddressingPolicyIsNot<Policy,NoAddressingPolicy>::type *)
+{
+    return do_accept(handle,address.sockaddr_p(),address.sockaddr_len());
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/CommunicationPolicy.hh b/Socket/CommunicationPolicy.hh
new file mode 100644 (file)
index 0000000..e5ad207
--- /dev/null
@@ -0,0 +1,68 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_CommunicationPolicy_
+#define HH_CommunicationPolicy_ 1
+
+// Custom includes
+#include "SocketPolicy.hh"
+#include "AddressingPolicy.hh"
+#include "FileHandle.hh"
+
+//#include "CommunicationPolicy.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+struct sockaddr;
+
+namespace satcom {
+namespace lib {
+    
+    template <class Policy> class ServerSocketHandle;
+
+    struct ConnectedCommunicationPolicy : public CommunicationPolicyBase
+    {
+        static void listen(FileHandle handle, unsigned backlog);
+        template <class Policy>
+        static int accept(ServerSocketHandle<Policy> handle, 
+                          typename ServerSocketHandle<Policy>::Address & address,
+                          typename IfAddressingPolicyIsNot<Policy,NoAddressingPolicy>::type * = 0);
+    private:
+        static int do_accept(FileHandle handle, struct sockaddr * addr, unsigned len);
+    };
+
+    struct UnconnectedCommunicationPolicy : public CommunicationPolicyBase
+    {};
+
+}}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "CommunicationPolicy.cci"
+//#include "CommunicationPolicy.ct"
+#include "CommunicationPolicy.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/Doxyfile b/Socket/Doxyfile
new file mode 100644 (file)
index 0000000..3a08b63
--- /dev/null
@@ -0,0 +1,273 @@
+# Doxyfile 1.4.2
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = ""
+PROJECT_NUMBER         = "Version 0.0.1"
+OUTPUT_DIRECTORY       = doc
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = NO
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = YES
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = YES
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = NO
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = .
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.C \
+                         *.CC \
+                         *.C++ \
+                         *.II \
+                         *.I++ \
+                         *.H \
+                         *.HH \
+                         *.H++ \
+                         *.CS \
+                         *.PHP \
+                         *.PHP3 \
+                         *.M \
+                         *.MM \
+                         *.cci \
+                         *.ct \
+                         *.cti \
+                         *.ih
+RECURSIVE              = NO
+EXCLUDE                = doc
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = *.test.cc
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 5
+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        = satcom.css
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# 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  = 
+PREDEFINED             = DOXYGEN
+EXPAND_AS_DEFINED      = DefineCommand
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = NO
+HAVE_DOT               = YES
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = NO
+DIRECTORY_GRAPH        = NO
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 800
+MAX_DOT_GRAPH_HEIGHT   = 1200
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = YES
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = NO
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/Socket/FileHandle.cc b/Socket/FileHandle.cc
new file mode 100644 (file)
index 0000000..4865ae6
--- /dev/null
@@ -0,0 +1,107 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "FileHandle.hh"
+//#include "FileHandle.ih"
+
+// Custom includes
+#include <unistd.h>
+#include <sys/poll.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "Utils/Exception.hh"
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void satcom::lib::FileBody::v_close()
+{
+    if (::close(fd_) != 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::FileBody::v_terminate()
+{
+    ::close(fd_);
+}
+
+prefix_ bool satcom::lib::FileBody::v_eof()
+    const
+{
+    return false;
+}
+
+prefix_ bool satcom::lib::FileBody::v_valid()
+    const
+{
+    return true;
+}
+
+prefix_ bool satcom::lib::FileBody::blocking()
+    const
+{
+    int flags = ::fcntl(fd(),F_GETFL);
+    if (flags < 0) throw SystemException(errno);
+    return ! (flags & O_NONBLOCK);
+}
+
+prefix_ void satcom::lib::FileBody::blocking(bool status)
+{
+    int flags = ::fcntl(fd(),F_GETFL);
+    if (flags < 0) throw SystemException(errno);
+    if (status) flags &= ~O_NONBLOCK;
+    else        flags |= O_NONBLOCK;
+    if (::fcntl(fd(), F_SETFL, flags) < 0) throw SystemException(errno);
+}
+
+prefix_ bool satcom::lib::FileBody::pollCheck(int fd, bool incoming, bool block)
+    const
+{
+    struct ::pollfd pfd;
+    ::memset(&pfd,0,sizeof(pfd));
+    pfd.fd = fd;
+    pfd.events = incoming?POLLIN:POLLOUT;
+    int rv = -1;
+    do {
+        rv = ::poll(&pfd,1,block?-1:0);
+        if (rv<0)
+            switch (errno) {
+            case EINTR:
+                break;
+            default:
+                throw SystemException(errno);
+            }
+    } while (rv<0);
+    return rv>0;
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/FileHandle.cci b/Socket/FileHandle.cci
new file mode 100644 (file)
index 0000000..f633fdf
--- /dev/null
@@ -0,0 +1,243 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+//#include "FileHandle.ih"
+
+// Custom includes
+#include <errno.h>
+#include "Utils/Exception.hh"
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::FileBody
+
+prefix_ satcom::lib::FileBody::FileBody(int fd)
+    : fd_(fd)
+{}
+
+prefix_  satcom::lib::FileBody::~FileBody()
+{
+    if (valid())
+        try {
+            close();
+        }
+        catch (...) {
+            terminate();
+        }
+}
+
+prefix_ void satcom::lib::FileBody::close()
+{
+    if (!valid())
+        throw SystemException(EBADF);
+    v_close();
+    fd_ = -1;
+}
+
+prefix_ void satcom::lib::FileBody::terminate()
+{
+    if (valid()) {
+        v_terminate();
+        fd_ = -1;
+    }
+}
+
+prefix_ int satcom::lib::FileBody::fd()
+    const
+{
+    return fd_;
+}
+
+prefix_ void satcom::lib::FileBody::fd(int fd)
+{
+    fd_ = fd;
+}
+
+prefix_ bool satcom::lib::FileBody::eof()
+    const
+{
+    return v_eof();
+}
+
+prefix_ bool satcom::lib::FileBody::valid()
+    const
+{
+    return fd_!=-1 && v_valid();
+}
+
+prefix_ bool satcom::lib::FileBody::readable()
+    const
+{
+    return pollCheck(fd(),true);
+}
+
+prefix_ void satcom::lib::FileBody::waitReadable()
+    const
+{
+    pollCheck(fd(),true,true);
+}
+
+prefix_ bool satcom::lib::FileBody::writeable()
+    const
+{
+    return pollCheck(fd(),false);
+}
+
+prefix_ void satcom::lib::FileBody::waitWriteable()
+    const
+{
+    pollCheck(fd(),false,true);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::FileHandle
+
+prefix_ void satcom::lib::FileHandle::close()
+{
+    body().close();
+}
+
+prefix_ void satcom::lib::FileHandle::terminate()
+{
+    body().terminate();
+}
+
+prefix_ bool satcom::lib::FileHandle::readable()
+    const
+{
+    return body().readable();
+}
+
+prefix_ void satcom::lib::FileHandle::waitReadable()
+    const
+{
+    body().waitReadable();
+}
+
+prefix_ bool satcom::lib::FileHandle::writeable()
+    const
+{
+    return body().writeable();
+}
+
+prefix_ void satcom::lib::FileHandle::waitWriteable()
+    const
+{
+    body().waitWriteable();
+}
+
+prefix_ bool satcom::lib::FileHandle::blocking()
+    const
+{
+    return body().blocking();
+}
+
+prefix_ void satcom::lib::FileHandle::blocking(bool status)
+{
+    body().blocking(status);
+}
+
+prefix_ bool satcom::lib::FileHandle::eof()
+    const
+{
+    return body().eof();
+}
+
+prefix_ bool satcom::lib::FileHandle::valid()
+    const
+{
+    return body().valid();
+}
+
+prefix_ satcom::lib::FileHandle::operator bool ()
+    const
+{
+    return valid() && !eof();
+}
+
+prefix_ bool satcom::lib::FileHandle::operator!()
+    const
+{
+    return ! (valid() && !eof());
+}
+
+prefix_ int satcom::lib::FileHandle::fd()
+    const
+{
+    return body().fd();
+}
+
+prefix_  satcom::lib::FileHandle::FileHandle(std::auto_ptr<FileBody> body)
+    : body_(body.release())
+{}
+
+prefix_ satcom::lib::FileBody & satcom::lib::FileHandle::body()
+{
+    return *body_;
+}
+
+prefix_ satcom::lib::FileBody const & satcom::lib::FileHandle::body()
+    const
+{
+    return *body_;
+}
+
+prefix_ satcom::lib::FileBody & satcom::lib::FileHandle::body(FileHandle & handle)
+{
+    return handle.body();
+}
+
+prefix_ satcom::lib::FileBody const &
+satcom::lib::FileHandle::body(FileHandle const & handle)
+{
+    return handle.body();
+}
+
+prefix_ void satcom::lib::FileHandle::fd(int fd)
+{
+    body().fd(fd);
+}
+
+prefix_ satcom::lib::FileHandle::FileHandle
+satcom::lib::FileHandle::cast_static(FileHandle handle)
+{
+    return handle;
+}
+
+prefix_ satcom::lib::FileHandle
+satcom::lib::FileHandle::cast_dynamic(FileHandle handle)
+{
+    return handle;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/FileHandle.hh b/Socket/FileHandle.hh
new file mode 100644 (file)
index 0000000..1f29b89
--- /dev/null
@@ -0,0 +1,106 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_FileHandle_
+#define HH_FileHandle_ 1
+
+// Custom includes
+#include <memory> // std::auto_ptr
+
+//#include "FileHandle.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+#include "FileHandle.ih"
+
+namespace satcom {
+namespace lib {
+    
+    /** \brief
+     */
+    class FileHandle
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        // protected default constructor
+        // default copy constructor
+        // default copy assignment
+        // default destructor
+
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+        
+        void close();
+        void terminate();
+
+        bool readable() const;
+        void waitReadable() const;
+        bool writeable() const;
+        void waitWriteable() const;
+
+        bool blocking() const;
+        void blocking(bool status);
+
+        bool eof() const;
+        bool valid() const;
+
+        operator bool () const;
+        bool operator!() const;
+
+        int fd() const;
+
+        static FileHandle cast_static(FileHandle handle);
+        static FileHandle cast_dynamic(FileHandle handle);
+
+    protected:
+        explicit FileHandle(std::auto_ptr<FileBody> body);
+
+        FileBody & body();
+        FileBody const & body() const;
+        static FileBody & body(FileHandle & handle);
+        static FileBody const & body(FileHandle const & handle);
+
+        void fd(int fd);
+
+    private:
+        FileBody::ptr body_;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "FileHandle.cci"
+//#include "FileHandle.ct"
+//#include "FileHandle.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/FileHandle.ih b/Socket/FileHandle.ih
new file mode 100644 (file)
index 0000000..8e59737
--- /dev/null
@@ -0,0 +1,103 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_FileHandle_
+#define IH_FileHandle_ 1
+
+// Custom includes
+#include <boost/intrusive_ptr.hpp>
+#include "Utils/intrusive_refcount.hh"
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    /** \brief
+      */
+    class FileBody
+        : public satcom::lib::intrusive_refcount
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+        
+        typedef boost::intrusive_ptr<FileBody> ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+        
+        explicit FileBody(int fd=-1);
+        virtual ~FileBody();
+
+        // no copy
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        int fd() const;
+        void fd(int fd);
+
+        void close();
+        void terminate();
+
+        bool readable() const;
+        void waitReadable() const;
+        bool writeable() const;
+        void waitWriteable() const;
+
+        bool blocking() const;
+        void blocking(bool status);
+
+        bool eof() const;
+        bool valid() const;
+        
+    private:
+        ///////////////////////////////////////////////////////////////////////////
+        // Virtual interface for subclasses to override
+
+        virtual void v_close();
+        virtual void v_terminate();
+        virtual bool v_eof() const;
+        virtual bool v_valid() const;
+        
+
+    protected:
+        
+    private:
+        bool pollCheck(int fd, bool incoming, bool block=false) const;
+
+        int fd_;
+    };
+
+}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/FileHandle.test.cc b/Socket/FileHandle.test.cc
new file mode 100644 (file)
index 0000000..c86a26b
--- /dev/null
@@ -0,0 +1,115 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "FileHandle.test.hh"
+//#include "FileHandle.test.ih"
+
+// Custom includes
+#include <iostream>
+#include <fcntl.h>
+#include <unistd.h>
+#include "FileHandle.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    class FHandle : public satcom::lib::FileHandle
+    {
+    public:
+        FHandle(int fd=-1) 
+            : satcom::lib::FileHandle(std::auto_ptr<satcom::lib::FileBody>(
+                                          new satcom::lib::FileBody(fd))) {}
+        FHandle(std::string name) 
+            : satcom::lib::FileHandle(std::auto_ptr<satcom::lib::FileBody>(
+                                          new satcom::lib::FileBody()))
+            {
+                int rv = ::open(name.c_str(),O_RDWR|O_NONBLOCK) ;
+                if (rv<0)
+                    throw satcom::lib::SystemException(errno);
+                fd(rv);
+            }
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(fileHandle)
+{
+    try {
+        {
+            FHandle fh("/dev/null");
+            BOOST_CHECK(fh.fd() != -1);
+            BOOST_CHECK(fh.valid());
+            BOOST_CHECK(fh);
+            BOOST_CHECK(!!fh);
+
+            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(),satcom::lib::SystemException);
+            BOOST_CHECK_NO_THROW(fh.terminate());
+        }
+        
+        {
+            FHandle fh("/dev/zero");
+            BOOST_CHECK(fh.readable());
+        }
+
+        {
+            int fds[2];
+            BOOST_REQUIRE(pipe(fds) == 0);
+
+            FHandle fh(fds[0]);
+            BOOST_CHECK(!fh.readable());
+
+            // Set non-blocking IO and fill the pipe buffer
+            int flags = fcntl(fds[1],F_GETFL,0);
+            if (flags == -1)
+                BOOST_FAIL(strerror(errno));
+            if (fcntl(fds[1],F_SETFL,flags|O_NONBLOCK) == -1)
+                BOOST_FAIL(strerror(errno));
+            char buffer[1024];
+            while (write(fds[1],buffer,1024) == 1024) ;
+
+            FHandle fh2(fds[1]);
+            BOOST_CHECK(!fh.writeable());
+        }
+    }
+    catch (std::exception const & ex) {
+        BOOST_FAIL(ex.what());
+    }
+}
+    
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/FramingPolicy.hh b/Socket/FramingPolicy.hh
new file mode 100644 (file)
index 0000000..96a4b98
--- /dev/null
@@ -0,0 +1,53 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_FramingPolicy_
+#define HH_FramingPolicy_ 1
+
+// Custom includes
+#include "SocketPolicy.hh"
+
+//#include "FramingPolicy.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    struct StreamFramingPolicy : public FramingPolicyBase
+    {};
+
+    struct DatagramFramingPolicy : public FramingPolicyBase
+    {};
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "FramingPolicy.cci"
+//#include "FramingPolicy.ct"
+//#include "FramingPolicy.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/GenericAddressingPolicy.cc b/Socket/GenericAddressingPolicy.cc
new file mode 100644 (file)
index 0000000..abb99f5
--- /dev/null
@@ -0,0 +1,96 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "GenericAddressingPolicy.hh"
+//#include "GenericAddressingPolicy.ih"
+
+// Custom includes
+#include <sys/socket.h>
+#include <sys/types.h>
+#include "Utils/Exception.hh"
+
+//#include "GenericAddressingPolicy.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void satcom::lib::GenericAddressingPolicy_Base::do_local(FileHandle handle,
+                                                                 struct sockaddr * addr,
+                                                                 unsigned len)
+{
+    if (::getsockname(handle.fd(),addr,&len) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::GenericAddressingPolicy_Base::do_peer(FileHandle handle,
+                                                                struct sockaddr * addr,
+                                                                unsigned len)
+{
+    if (::getpeername(handle.fd(),addr,&len) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::GenericAddressingPolicy_Base::do_bind(FileHandle handle,
+                                                                struct sockaddr const * addr,
+                                                                unsigned len)
+{
+    if (::bind(handle.fd(),addr,len) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::GenericAddressingPolicy_Base::do_connect(FileHandle handle,
+                                                                   struct sockaddr const * addr,
+                                                                   unsigned len)
+{
+    while(1) {
+        if (::connect(handle.fd(),addr,len) < 0) 
+            switch (errno) {
+            case EINPROGRESS: {
+                handle.waitWriteable();
+                int err = 0;
+                socklen_t len = sizeof(err);
+                if (::getsockopt(handle.fd(),SOL_SOCKET,SO_ERROR,&err,&len) < 0)
+                    throw SystemException(errno);
+                if (err != 0)
+                    throw SystemException(err);
+                return;
+            }
+            case EINTR:
+                break;
+            default:
+                throw SystemException(errno);
+            }
+        else
+            return;
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "GenericAddressingPolicy.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/GenericAddressingPolicy.cti b/Socket/GenericAddressingPolicy.cti
new file mode 100644 (file)
index 0000000..cb0d400
--- /dev/null
@@ -0,0 +1,76 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "GenericAddressingPolicy.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::GenericAddressingPolicy<Address>
+
+template <class Address>
+template <class Policy>
+prefix_ void satcom::lib::GenericAddressingPolicy<Address>::
+peer(SocketHandle<Policy> handle, Address & addr,
+     typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type *)
+{
+    addr.clear();
+    do_peer(handle,addr.sockaddr_p(),addr.sockaddr_len());
+}
+
+template <class Address>
+template <class Policy>
+prefix_ void satcom::lib::GenericAddressingPolicy<Address>::
+connect(SocketHandle<Policy> handle, Address const & addr,
+        typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type *)
+{
+    do_connect(handle,addr.sockaddr_p(),addr.sockaddr_len());
+}
+
+template <class Address>
+prefix_ void satcom::lib::GenericAddressingPolicy<Address>::local(FileHandle handle,
+                                                                  Address & addr)
+{
+    addr.clear();
+    do_local(handle,addr.sockaddr_p(),addr.sockaddr_len());
+}
+
+template <class Address>
+prefix_ void satcom::lib::GenericAddressingPolicy<Address>::bind(FileHandle handle,
+                                                                 Address const & addr)
+{
+    do_bind(handle,addr.sockaddr_p(),addr.sockaddr_len());
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/GenericAddressingPolicy.hh b/Socket/GenericAddressingPolicy.hh
new file mode 100644 (file)
index 0000000..da55c11
--- /dev/null
@@ -0,0 +1,74 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_GenericAddressingPolicy_
+#define HH_GenericAddressingPolicy_ 1
+
+// Custom includes
+#include "SocketHandle.hh"
+#include "FileHandle.hh"
+#include "SocketPolicy.hh"
+#include "CommunicationPolicy.hh"
+
+//#include "GenericAddressingPolicy.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    struct GenericAddressingPolicy_Base
+    {
+        static void do_local(FileHandle handle, struct sockaddr * addr, unsigned len);
+        static void do_peer(FileHandle handle, struct sockaddr * addr, unsigned len);
+        static void do_bind(FileHandle handle, struct sockaddr const * addr, unsigned len);
+        static void do_connect(FileHandle handle, struct sockaddr const * addr, unsigned len);
+    };
+
+    template <class Address>
+    struct GenericAddressingPolicy
+        : private GenericAddressingPolicy_Base
+    {
+        template <class Policy>
+        static void peer(SocketHandle<Policy> handle, Address & addr,
+                         typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0);
+        static void local(FileHandle handle, Address & addr);
+
+        template <class Policy>
+        static void connect(SocketHandle<Policy> handle, Address const & addr,
+                            typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0);
+        static void bind(FileHandle handle, Address const & addr);
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "GenericAddressingPolicy.cci"
+//#include "GenericAddressingPolicy.ct"
+#include "GenericAddressingPolicy.cti"
+//#include "GenericAddressingPolicy.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/INetAddressing.cc b/Socket/INetAddressing.cc
new file mode 100644 (file)
index 0000000..b2e8edf
--- /dev/null
@@ -0,0 +1,87 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "INetAddressing.hh"
+//#include "INetAddressing.ih"
+
+// Custom includes
+#include <strstream>
+#include <string.h>
+#include <sys/socket.h>
+#include <boost/lexical_cast.hpp>
+
+//#include "INetAddressing.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ satcom::lib::INet4Address::INet4Address(std::string host, unsigned port)
+{
+    clear();
+    // TODO: gethostbyname einbauen
+    if (::inet_aton(host.c_str(), &addr_.sin_addr) == 0)
+        throw InvalidINetAddressException();
+    addr_.sin_port = htons(port);
+}
+
+prefix_ std::string satcom::lib::INet4Address::str()
+    const
+{
+    std::stringstream s;
+    s << host() << ':' << port();
+    return s.str();
+}
+
+prefix_ void satcom::lib::INet4Address::clear()
+{
+    ::memset(&addr_,0,sizeof(addr_));
+    addr_.sin_family = AF_INET;
+}
+
+prefix_ void satcom::lib::INet4Address::assignString(std::string address)
+{
+    clear();
+    // TODO: gethostbyname einbauen
+    unsigned i = address.find(':');
+    if (i == std::string::npos)
+        throw InvalidINetAddressException();
+    if (::inet_aton(std::string(address,0,i).c_str(), &addr_.sin_addr) == 0)
+        throw InvalidINetAddressException();
+    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 & ex) {
+        throw InvalidINetAddressException();
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "INetAddressing.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/INetAddressing.cci b/Socket/INetAddressing.cci
new file mode 100644 (file)
index 0000000..a04def2
--- /dev/null
@@ -0,0 +1,96 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+// Custom includes
+#include <arpa/inet.h>
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ satcom::lib::INet4Address::INet4Address()
+{
+    clear();
+}
+
+prefix_ satcom::lib::INet4Address::INet4Address(char const * address)
+{
+    assignString(address);
+}
+
+prefix_ satcom::lib::INet4Address::INet4Address(std::string address)
+{
+    assignString(address);
+}
+
+prefix_ bool satcom::lib::INet4Address::operator==(INet4Address const & other)
+    const
+{
+    return addr_.sin_port == other.addr_.sin_port && 
+        addr_.sin_addr.s_addr == other.addr_.sin_addr.s_addr;
+}
+
+prefix_ std::string satcom::lib::INet4Address::host()
+    const
+{
+    // FIXME: thread safety?
+    return std::string(::inet_ntoa(addr_.sin_addr));
+}
+
+prefix_ unsigned satcom::lib::INet4Address::port()
+    const
+{
+    return ntohs(addr_.sin_port);
+}
+
+prefix_ struct sockaddr * satcom::lib::INet4Address::sockaddr_p()
+{
+    return reinterpret_cast<struct sockaddr *>(&addr_);
+}
+
+prefix_ struct sockaddr const * satcom::lib::INet4Address::sockaddr_p()
+    const
+{
+    return reinterpret_cast<struct sockaddr const *>(&addr_);
+}
+
+prefix_ unsigned satcom::lib::INet4Address::sockaddr_len()
+    const
+{
+    return sizeof(addr_);
+}
+
+prefix_ std::ostream & satcom::lib::operator<<(std::ostream & os, INet4Address const & addr)
+{
+    os << addr.str();
+    return os;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/INetAddressing.hh b/Socket/INetAddressing.hh
new file mode 100644 (file)
index 0000000..28a8a59
--- /dev/null
@@ -0,0 +1,114 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_INetAddressing_
+#define HH_INetAddressing_ 1
+
+// Custom includes
+#include <string>
+#include <exception>
+#include <netinet/in.h>
+#include "SocketPolicy.hh"
+#include "ClientSocketHandle.hh"
+#include "CommunicationPolicy.hh"
+#include "GenericAddressingPolicy.hh"
+
+//#include "INetAddressing.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    // TODO: Implement real INet4Address datatype and 
+    // rename this one to INet4SockAddress ...
+
+    class INet4Address
+    {
+    public:
+        INet4Address();
+        INet4Address(char const * address);
+        INet4Address(std::string address);
+        INet4Address(std::string host, unsigned port);
+
+        bool operator==(INet4Address const & other) const;
+
+        std::string str() const;
+        std::string host() const;
+        unsigned port() const;
+
+        // TODO: Interface
+
+        void clear();
+
+        struct sockaddr * sockaddr_p();
+        struct sockaddr const * sockaddr_p() const;
+        unsigned sockaddr_len() const;
+
+    private:
+        void assignString(std::string addr);
+        
+        struct ::sockaddr_in addr_;
+    };
+
+    std::ostream & operator<<(std::ostream & os, INet4Address const & addr);
+
+    class INet6Address
+    {
+        // TODO: Implement
+    };
+    
+    struct INet4AddressingPolicy 
+        : public AddressingPolicyBase,
+          private GenericAddressingPolicy<INet4Address>
+    {
+        typedef INet4Address Address;
+
+        using GenericAddressingPolicy<INet4Address>::peer;
+        using GenericAddressingPolicy<INet4Address>::local;
+        using GenericAddressingPolicy<INet4Address>::connect;
+        using GenericAddressingPolicy<INet4Address>::bind;
+    };
+
+    struct INet6AddressingPolicy : public AddressingPolicyBase
+    {
+        typedef INet6Address Address;
+
+        // TODO: Implement
+    };
+
+    struct InvalidINetAddressException : public std::exception
+    { char const * what() const throw() { return "invalid inet address"; } };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "INetAddressing.cci"
+//#include "INetAddressing.ct"
+//#include "INetAddressing.cti"
+//#include "INetAddressing.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/INetAddressing.test.cc b/Socket/INetAddressing.test.cc
new file mode 100644 (file)
index 0000000..dea7b88
--- /dev/null
@@ -0,0 +1,89 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "INetAddressing.test.hh"
+//#include "INetAddressing.test.ih"
+
+// Custom includes
+#include "INetAddressing.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(inet4Address)
+{
+    using satcom::lib::INet4Address;
+    using satcom::lib::InvalidINetAddressException;
+
+    {
+        INet4Address addr;
+    
+        addr = "127.0.0.1:12345";
+    }
+    
+    {
+        INet4Address addr1("127.0.0.1:12345");
+        INet4Address addr2(std::string("127.0.0.1:12345"));
+        INet4Address addr3("127.0.0.1",12345);
+    }
+
+    BOOST_CHECK_EQUAL( INet4Address("127.0.0.1:12345"), INet4Address("127.0.0.1",12345) );
+
+    BOOST_CHECK_THROW( INet4Address("127.0.0.1"), InvalidINetAddressException );
+    BOOST_CHECK_THROW( INet4Address("foo@bar:12345"), InvalidINetAddressException );
+    BOOST_CHECK_THROW( INet4Address("127.0.0.1:1234a"), InvalidINetAddressException );
+    BOOST_CHECK_THROW( INet4Address("foo@bar",12345), InvalidINetAddressException );
+
+    BOOST_CHECK_EQUAL( INet4Address("127.0.0.1:12345").host(), "127.0.0.1" );
+    BOOST_CHECK_EQUAL( INet4Address("127.0.0.1:12345").port(), 12345u );
+    BOOST_CHECK_EQUAL( INet4Address("127.0.0.1:12345").str(), "127.0.0.1:12345" );
+
+    {
+        INet4Address addr("127.0.0.1:12345");
+        BOOST_CHECK_EQUAL( reinterpret_cast< ::sockaddr_in * >(addr.sockaddr_p())->sin_port,
+                           htons(12345) );
+        BOOST_CHECK_EQUAL( reinterpret_cast< ::sockaddr_in * >(addr.sockaddr_p())->sin_addr.s_addr,
+                           htonl(INADDR_LOOPBACK) );
+
+        std::stringstream s;
+        s << addr;
+        BOOST_CHECK_EQUAL( s.str(), "127.0.0.1:12345" );
+    }
+}
+
+BOOST_AUTO_UNIT_TEST(inet6Address)
+{
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/INetProtocol.cc b/Socket/INetProtocol.cc
new file mode 100644 (file)
index 0000000..b66e15d
--- /dev/null
@@ -0,0 +1,159 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "INetProtocol.hh"
+//#include "INetProtocol.ih"
+
+// Custom includes
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h> // for if_nametoindex
+#include "Utils/Exception.hh"
+
+//#include "INetProtocol.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::INet4Protocol
+
+prefix_ void satcom::lib::IPv4Protocol::connect(INet4Address const & address)
+    const
+{
+    if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::IPv4Protocol::bind(INet4Address const & address)
+    const
+{
+    if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ bool satcom::lib::IPv4Protocol::mcLoop()
+    const
+{
+    int value;
+    socklen_t len (sizeof(value));
+    if (::getsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0)
+        throw SystemException(errno);
+    return value;
+}
+
+prefix_ void satcom::lib::IPv4Protocol::mcLoop(bool value)
+    const
+{
+    int ivalue (value);
+    if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::IPv4Protocol::mcAddMembership(INet4Address const & mcAddr)
+    const
+{
+    struct ip_mreqn mreqn;
+    mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
+    mreqn.imr_address.s_addr = htons(INADDR_ANY);
+    mreqn.imr_ifindex = 0;
+    if (::setsockopt(body().fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::IPv4Protocol::mcAddMembership(INet4Address const & mcAddr,
+                                                        INet4Address const & localAddr)
+    const
+{
+    struct ip_mreqn mreqn;
+    mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
+    mreqn.imr_address = reinterpret_cast<struct sockaddr_in const *>(localAddr.sockaddr_p())->sin_addr;
+    mreqn.imr_ifindex = 0;
+    if (::setsockopt(body().fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::IPv4Protocol::mcDropMembership(INet4Address const & mcAddr)
+    const
+{
+    struct ip_mreqn mreqn;
+    mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
+    mreqn.imr_address.s_addr = htons(INADDR_ANY);
+    mreqn.imr_ifindex = 0;
+    if (::setsockopt(body().fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::IPv4Protocol::mcDropMembership(INet4Address const & mcAddr,
+                                                         INet4Address const & localAddr)
+    const
+{
+    struct ip_mreqn mreqn;
+    mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
+    mreqn.imr_address = reinterpret_cast<struct sockaddr_in const *>(localAddr.sockaddr_p())->sin_addr;
+    mreqn.imr_ifindex = 0;
+    if (::setsockopt(body().fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::IPv4Protocol::mcIface(std::string iface)
+    const
+{
+    struct ip_mreqn mreqn;
+    ::memset(&mreqn,sizeof(mreqn),0);
+    if (!iface.empty()) {
+        mreqn.imr_ifindex = if_nametoindex(iface.c_str());
+        if (mreqn.imr_ifindex == 0)
+            throw SystemException(EINVAL);
+    }
+    if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ unsigned satcom::lib::IPv4Protocol::mcTTL()
+    const
+{
+    int value;
+    socklen_t len (sizeof(value));
+    if (::getsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0)
+        throw SystemException(errno);
+    return value;
+}
+
+prefix_ void satcom::lib::IPv4Protocol::mcTTL(unsigned value)
+    const
+{
+    if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0)
+        throw SystemException(errno);
+}
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "INetProtocol.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/INetProtocol.hh b/Socket/INetProtocol.hh
new file mode 100644 (file)
index 0000000..a5a3cd6
--- /dev/null
@@ -0,0 +1,89 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// TODO: what about OOB data? das OOB Data block receipt of normal data ?
+
+// TODO: Implement IP_RECVERR / MSG_ERRQUEUE. This should be placed
+// into an additional protocol class since IP_RECVERR is only valid
+// for SOCK_DGRAM (UDP) and not SOCK_STREAM (TCP) sockets
+
+#ifndef HH_INetProtocol_
+#define HH_INetProtocol_ 1
+
+// Custom includes
+#include "SocketProtocol.hh"
+#include "INetAddressing.hh"
+#include "ClientSocketHandle.hh"
+#include "CommunicationPolicy.hh"
+
+//#include "INetProtocol.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    class IPv4Protocol 
+        : public virtual SocketProtocol
+    {
+    public:
+        void connect(INet4Address const & address) const;
+        void bind(INet4Address const & address) const;
+
+        unsigned mcTTL() const;
+        void mcTTL(unsigned value) const;
+
+        bool mcLoop() const;
+        void mcLoop(bool value) const;
+
+        // 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 ?)
+       
+        // TODO: move all multicast-methods into an extra
+        // IPv4MulticastProtocol class
+
+        void mcAddMembership(INet4Address const & mcAddr) const;
+        void mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr) const;
+
+        void mcDropMembership(INet4Address const & mcAddr) const;
+        void mcDropMembership(INet4Address const & mcAddr, INet4Address const & localAddr) const;
+
+        void mcIface(std::string iface = std::string()) const;
+    };
+    
+    class IPv6Protocol
+        : public virtual SocketProtocol
+    {};
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "INetProtocol.cci"
+//#include "INetProtocol.ct"
+//#include "INetProtocol.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/LLAddressing.cc b/Socket/LLAddressing.cc
new file mode 100644 (file)
index 0000000..6ef9508
--- /dev/null
@@ -0,0 +1,128 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "LLAddressing.hh"
+#include "LLAddressing.ih"
+
+// Custom includes
+#include <net/if.h>
+#include <sys/socket.h>
+
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/finder.hpp>
+
+#include "Utils/Exception.hh"
+
+//#include "LLAddressing.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ unsigned char satcom::lib::detail::hexnibble(char c)
+{
+    if (c>='0' && c<='9')
+        return c - '0';
+    if (c>='A' && c<='F')
+        return c - 'A' + 10;
+    if (c>='a' && c<='f')
+        return c - 'a' + 10;
+    throw InvalidLLSocketAddressException();
+}
+
+prefix_ std::string satcom::lib::LLSocketAddress::interface()
+    const
+{
+    if (addr_.sll_ifindex == 0)
+        return std::string();
+    char name[IFNAMSIZ];
+    if (! ::if_indextoname(addr_.sll_ifindex, name))
+        throw InvalidLLSocketAddressException();
+    return std::string(name);
+}
+
+/*
+{
+    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);
+        ++i;
+        if (i == &addr_.sll_addr[addr_.sll_halen]) break;
+        s << '-';
+    }
+    return s.str();
+}
+*/
+
+
+/*
+prefix_ void satcom::lib::LLSocketAddress::address(std::string address)
+{
+    typedef boost::split_iterator<std::string::iterator> StringSplitIterator;
+    StringSplitIterator i = boost::make_split_iterator(address, boost::token_finder(boost::is_any_of("-: ")));
+    unsigned char * j = &addr_.sll_addr[0];
+    for (; ! i.eof() && addr_.sll_halen<8; ++i, ++j, ++addr_.sll_halen) {
+        if ( i->size() != 2 || ! boost::all(*i, boost::is_xdigit()) )
+            throw InvalidLLSocketAddressException();
+        *j = hex(*i);
+    }
+    if (! i.eof())
+        throw InvalidLLSocketAddressException();
+}
+*/
+
+prefix_ void satcom::lib::LLSocketAddress::interface(std::string interface)
+{
+    if (! interface.empty()) {
+        addr_.sll_ifindex = if_nametoindex(interface.c_str());
+        if (addr_.sll_ifindex == 0)
+            throw InvalidLLSocketAddressException();
+    }
+}
+
+
+prefix_ satcom::lib::detail::LLAddressFromStringRange
+satcom::lib::llAddress(std::string address)
+{
+    detail::StringSplitIterator i = 
+        boost::make_split_iterator(address, boost::token_finder(boost::is_any_of("-: ")));
+    detail::StringSplitIterator i_end;
+
+    detail::HexSplitIterator j (i,detail::HexConverter());
+    detail::HexSplitIterator j_end (i_end);
+
+    return detail::LLAddressFromStringRange(j,j_end);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "LLAddressing.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/LLAddressing.cci b/Socket/LLAddressing.cci
new file mode 100644 (file)
index 0000000..3de8a5e
--- /dev/null
@@ -0,0 +1,113 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+// Custom includes
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ satcom::lib::LLSocketAddress::LLSocketAddress()
+{
+    clear();
+}
+
+prefix_ satcom::lib::LLSocketAddress::LLSocketAddress(unsigned protocol, std::string interface)
+{
+    clear();
+    this->protocol(protocol);
+    this->interface(interface);
+}
+
+prefix_  satcom::lib::LLSocketAddress::LLSocketAddress(std::string interface)
+{
+    clear();
+    this->interface(interface);
+}
+
+prefix_ void satcom::lib::LLSocketAddress::clear()
+{
+    ::memset(&addr_,0,sizeof(addr_));
+    addr_.sll_family = AF_PACKET;
+}
+
+prefix_ unsigned satcom::lib::LLSocketAddress::protocol()
+    const
+{
+    return ntohs(addr_.sll_protocol);
+}
+
+prefix_ unsigned satcom::lib::LLSocketAddress::arptype()
+    const
+{
+    // TODO: Check, wether this is returned in network or host byte
+    // order
+    return ntohs(addr_.sll_hatype);
+}
+
+prefix_ unsigned satcom::lib::LLSocketAddress::pkttype()
+    const
+{
+    // TODO: Check, wether this is returned in network or host byte
+    // order
+    return ntohs(addr_.sll_pkttype);
+}
+
+prefix_ satcom::lib::LLSocketAddress::LLAddress satcom::lib::LLSocketAddress::address()
+    const
+{
+    return LLAddress(&addr_.sll_addr[0], &addr_.sll_addr[addr_.sll_halen]);
+}
+
+prefix_ void satcom::lib::LLSocketAddress::protocol(unsigned protocol)
+{
+    addr_.sll_protocol = htons(protocol);
+}
+
+prefix_ struct sockaddr * satcom::lib::LLSocketAddress::sockaddr_p()
+{
+    return reinterpret_cast<struct sockaddr *>(&addr_);
+}
+
+prefix_ struct sockaddr const * satcom::lib::LLSocketAddress::sockaddr_p()
+    const
+{
+    return reinterpret_cast<struct sockaddr const *>(&addr_);
+}
+
+prefix_ unsigned satcom::lib::LLSocketAddress::sockaddr_len()
+    const
+{
+    return sizeof(addr_);
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/LLAddressing.ct b/Socket/LLAddressing.ct
new file mode 100644 (file)
index 0000000..cf38dd4
--- /dev/null
@@ -0,0 +1,86 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+#include "LLAddressing.ih"
+
+// Custom includes
+#include <sstream>
+#include <iomanip>
+#include <string.h>
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class ForwardRange>
+prefix_ void satcom::lib::LLSocketAddress::address(ForwardRange const & address)
+{
+    if (boost::size(address) > sizeof(addr_.sll_addr))
+        throw InvalidLLSocketAddressException();
+    typename boost::range_const_iterator<ForwardRange>::type i (boost::begin(address));
+    ::memset(&addr_.sll_addr[0],sizeof(addr_.sll_addr),0);
+    addr_.sll_halen = 0;
+    for (; i != boost::end(address) && addr_.sll_halen<8; ++i, ++addr_.sll_halen)
+        addr_.sll_addr[addr_.sll_halen] = *i;
+    if (i != boost::end(address))
+        throw InvalidLLSocketAddressException();
+}
+
+template <class ForwardRange>
+prefix_ std::string
+satcom::lib::llAddress(ForwardRange const & address,
+                       typename boost::enable_if< boost::is_class<ForwardRange> >::type *)
+{
+    if (boost::empty(address))
+        return std::string();
+    std::stringstream s;
+    typename boost::range_const_iterator< ForwardRange >::type i (boost::begin(address));
+    while (1) {
+        s << std::hex << std::setw(2) << std::setfill('0') << unsigned(*i);
+        ++ i;
+        if (i == boost::end(address))
+            break;
+        s << '-';
+    }
+    return s.str();
+}
+
+template <class ForwardRange>
+prefix_ unsigned char satcom::lib::detail::HexConverter::operator()(ForwardRange const & v)
+    const
+{
+    if (boost::size(v) != 2)
+        throw InvalidLLSocketAddressException();
+    typename boost::range_iterator< ForwardRange >::type i (boost::begin(v));
+    unsigned char n1 = hexnibble(*i) << 4;
+    return n1 + hexnibble(*(++i));
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/LLAddressing.cti b/Socket/LLAddressing.cti
new file mode 100644 (file)
index 0000000..c1a5e68
--- /dev/null
@@ -0,0 +1,50 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+#include "LLAddressing.ih"
+
+// Custom includes
+#include <algorithm> // for std::copy
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class ForwardRange>
+prefix_ satcom::lib::LLSocketAddress::
+LLSocketAddress(ForwardRange const & address, std::string interface,
+                typename boost::enable_if_c<! boost::is_integral<ForwardRange>::value >::type *)
+{
+    clear();
+    this->address(address);
+    this->interface(interface);
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/LLAddressing.hh b/Socket/LLAddressing.hh
new file mode 100644 (file)
index 0000000..ce699be
--- /dev/null
@@ -0,0 +1,138 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_LLAddressing_
+#define HH_LLAddressing_ 1
+
+// Custom includes
+#include <boost/range/iterator_range.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <sys/socket.h>
+#include <netpacket/packet.h>
+
+#include "SocketPolicy.hh"
+#include "FileHandle.hh"
+#include "GenericAddressingPolicy.hh"
+
+//#include "LLAddressing.mpp"
+#include "LLAddressing.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    class LLSocketAddress
+    {
+    public:
+        // Right now we use an arbitrary ForwardRange (see Boost.Range)
+        // as the representation for a hardware address. The restrictions
+        // for the range are:
+        // a) the range must never be larger than 8 elements
+        // b) the value_type must be convertible to unsigend char
+        // and really we need only a single-pass range.
+        //
+        // Since a hardware address is so short (a maximum of 8
+        // bytes), in the aftermath I think a simple container holding
+        // a maximum of 8 unsigned chars (e.g. Boost.Array with
+        // additional length parameter) will be much simpler and
+        // probably even more efficient. This should have a conversion
+        // constructor from an arbitrary ForwardRange to make it
+        // compatible e.g. with the Packet library.
+        //
+        // However, since I have implemented it already as it is now,
+        // 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="");
+        explicit LLSocketAddress(std::string interface);
+        // This is for sending packets ..
+        // We must use enable_if here, so this constructor will not hide
+        // above constructor if passed a plain int or short argument
+        template <class ForwardRange>
+        explicit LLSocketAddress(ForwardRange const & address, std::string interface="",
+                                 typename boost::enable_if_c<! boost::is_integral<ForwardRange>::value >::type * = 0);
+
+        void clear();
+
+        unsigned protocol() const;
+        std::string interface() const;
+        unsigned arptype() const;
+        unsigned pkttype() const;
+        LLAddress address() const;
+
+        // The mutating interface is purposely restricted to allow only
+        // changing those members, which are sensible to be changed.
+
+        template <class ForwardRange>
+        void address(ForwardRange const & address);
+        void interface(std::string interface);
+        void protocol(unsigned protocol);
+
+        struct sockaddr * sockaddr_p();
+        struct sockaddr const * sockaddr_p() const;
+        unsigned sockaddr_len() const;
+
+    private:
+        struct ::sockaddr_ll addr_;
+    };
+
+    detail::LLAddressFromStringRange llAddress(std::string address);
+    // The enable_if condition here allows only for classes as range.
+    // However, excluding zero-terminated strings (which we want to
+    // pass to above) I cannot think of a non-class ForwardRange
+    // except for academic cases
+    template <class ForwardRange>
+    std::string llAddress(ForwardRange const & address,
+                          typename boost::enable_if< boost::is_class<ForwardRange> >::type * = 0);
+
+    class LLAddressingPolicy
+        : public AddressingPolicyBase,
+          private GenericAddressingPolicy<LLSocketAddress>
+    {
+    public:
+        typedef LLSocketAddress Address;
+
+        using GenericAddressingPolicy<LLSocketAddress>::local;
+        using GenericAddressingPolicy<LLSocketAddress>::bind;
+    };
+
+    struct InvalidLLSocketAddressException : public std::exception
+    { char const * what() const throw() { return "invalid ll address"; } };
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "LLAddressing.cci"
+#include "LLAddressing.ct"
+#include "LLAddressing.cti"
+//#include "LLAddressing.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/LLAddressing.ih b/Socket/LLAddressing.ih
new file mode 100644 (file)
index 0000000..57ec8b1
--- /dev/null
@@ -0,0 +1,56 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_LLAddressing_
+#define IH_LLAddressing_ 1
+
+// Custom includes
+#include <boost/algorithm/string/split.hpp>
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+namespace detail {
+
+    struct HexConverter {
+        typedef unsigned char result_type;
+        template <class ForwardRange>
+        result_type operator()(ForwardRange const & v) const;
+    };
+
+    typedef boost::split_iterator<std::string::iterator> StringSplitIterator;
+    typedef boost::transform_iterator< HexConverter, StringSplitIterator > HexSplitIterator;
+    typedef boost::iterator_range<HexSplitIterator> LLAddressFromStringRange;
+
+    unsigned char hexnibble(char c);
+
+}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/LLAddressing.test.cc b/Socket/LLAddressing.test.cc
new file mode 100644 (file)
index 0000000..cdbbe45
--- /dev/null
@@ -0,0 +1,85 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "LLAddressing.test.hh"
+//#include "LLAddressing.test.ih"
+
+// Custom includes
+#include "LLAddressing.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(llAddress)
+{
+    { 
+        satcom::lib::LLSocketAddress a;
+
+        BOOST_CHECK_EQUAL( a.protocol(), 0u );
+        BOOST_CHECK_EQUAL( a.interface(), "" );
+        BOOST_CHECK_EQUAL( a.arptype(), 0u );
+        BOOST_CHECK_EQUAL( a.pkttype(), 0u );
+        BOOST_CHECK_EQUAL( a.address(), "" );
+
+        a.address(satcom::lib::llAddress("05-10-1A-2f-25-30"));
+        BOOST_CHECK_EQUAL( satcom::lib::llAddress(a.address()), "05-10-1a-2f-25-30" );
+        a.interface("lo");
+        BOOST_CHECK_EQUAL( a.interface(), "lo" );
+        a.protocol(123);
+        BOOST_CHECK_EQUAL( a.protocol(), 123u );
+    }
+    
+    {
+        satcom::lib::LLSocketAddress a (
+            satcom::lib::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 );
+        BOOST_CHECK_EQUAL( a.pkttype(), 0u );
+        BOOST_CHECK_EQUAL( satcom::lib::llAddress(a.address()), "11-12-13-14-15-16" );
+    }
+
+    {
+        satcom::lib::LLSocketAddress a (123, "lo");
+        
+        BOOST_CHECK_EQUAL( a.protocol(), 123u );
+        BOOST_CHECK_EQUAL( a.interface(), "lo" );
+        BOOST_CHECK_EQUAL( a.arptype(), 0u );
+        BOOST_CHECK_EQUAL( a.pkttype(), 0u );
+        BOOST_CHECK_EQUAL( satcom::lib::llAddress(a.address()), "" );
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/PacketSocketHandle.cc b/Socket/PacketSocketHandle.cc
new file mode 100644 (file)
index 0000000..4dc8791
--- /dev/null
@@ -0,0 +1,127 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "PacketSocketHandle.hh"
+#include "PacketSocketHandle.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netpacket/packet.h>
+#include <net/ethernet.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <errno.h>
+
+//#include "PacketSocketHandle.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void satcom::lib::PacketProtocol::init_client(SocketType type, int protocol)
+    const
+{
+    int socktype = SOCK_RAW;
+    if (type == DatagramSocket)
+        socktype = SOCK_DGRAM;
+    if (protocol == -1)
+        protocol = ETH_P_ALL;
+    int sock = ::socket(PF_PACKET, socktype, htons(protocol));
+    if (sock < 0)
+        throw SystemException(errno);
+    body().fd(sock);
+}
+
+prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::PacketProtocol::clone()
+    const
+{
+    return std::auto_ptr<SocketProtocol>(new PacketProtocol());
+}
+
+prefix_ unsigned satcom::lib::PacketProtocol::available()
+    const
+{
+    if (! body().readable())
+        return 0;
+    ssize_t l = ::recv(body().fd(),0,0,MSG_PEEK | MSG_TRUNC);
+    if (l < 0)
+        throw SystemException(errno);
+    return l;
+}
+
+prefix_ bool satcom::lib::PacketProtocol::eof()
+    const
+{
+    return false;
+}
+
+prefix_ void satcom::lib::PacketProtocol::promisc(std::string interface, PromiscMode mode)
+    const
+{
+    // 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
+
+    struct packet_mreq mreq;
+    mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
+    if (mreq.mr_ifindex == 0)
+        throw SystemException(EINVAL);
+    mreq.mr_alen = 0;
+
+    mreq.mr_type = PACKET_MR_PROMISC;
+    int command = mode == Promiscuous ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP;
+    if (::setsockopt(body().fd(),SOL_PACKET,command,&mreq,sizeof(mreq)) < 0)
+        throw SystemException(errno);
+
+    mreq.mr_type = PACKET_MR_ALLMULTI;
+    command = mode == AllMulticast ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP;
+    if (::setsockopt(body().fd(),SOL_PACKET,command,&mreq,sizeof(mreq)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::PacketProtocol::do_mc_i(std::string interface,
+                                                  detail::LLAddressCopier const & copier, bool add)
+    const
+{
+    struct packet_mreq mreq;
+    mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
+    if (mreq.mr_ifindex == 0)
+        throw SystemException(EINVAL);
+    mreq.mr_type = PACKET_MR_MULTICAST;
+    mreq.mr_alen = copier(&mreq.mr_address[0]);
+    if (::setsockopt(body().fd(),SOL_PACKET,
+                     add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
+                     &mreq, sizeof(mreq)) < 0)
+        throw SystemException(errno);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "PacketSocketHandle.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/PacketSocketHandle.ct b/Socket/PacketSocketHandle.ct
new file mode 100644 (file)
index 0000000..964ca76
--- /dev/null
@@ -0,0 +1,53 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+#include "PacketSocketHandle.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class ForwardRange>
+prefix_ unsigned
+satcom::lib::detail::Range_LLAddressCopier<ForwardRange>::operator()(unsigned char * target)
+    const
+{
+    std::size_t len (0);
+    typename boost::range_const_iterator<ForwardRange>::type i (boost::begin(range_));
+    for (; i != boost::end(range_) && len<8; ++i, ++len, ++target)
+        *target = *i;
+    if (i != boost::end(range_))
+        throw InvalidLLSocketAddressException();
+    return len;
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/PacketSocketHandle.cti b/Socket/PacketSocketHandle.cti
new file mode 100644 (file)
index 0000000..a612e18
--- /dev/null
@@ -0,0 +1,70 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+#include "PacketSocketHandle.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class ForwardRange>
+prefix_ void satcom::lib::PacketProtocol::mcAdd(std::string interface,
+                                                ForwardRange const & address)
+    const
+{
+    do_mc(interface,address,true);
+}
+
+template <class ForwardRange>
+prefix_ void satcom::lib::PacketProtocol::mcDrop(std::string interface,
+                                                 ForwardRange const & address)
+    const
+{
+    do_mc(interface,address,false);
+}
+
+template <class ForwardRange>
+prefix_ satcom::lib::detail::Range_LLAddressCopier<ForwardRange>::
+Range_LLAddressCopier(ForwardRange const & range)
+    : range_ (range) 
+{}
+
+template <class ForwardRange>
+prefix_ void satcom::lib::PacketProtocol::do_mc(std::string interface,
+                                                ForwardRange const & address, bool add)
+    const
+{
+    detail::Range_LLAddressCopier<ForwardRange> copier (address);
+    do_mc_i(interface, copier, add);
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/PacketSocketHandle.hh b/Socket/PacketSocketHandle.hh
new file mode 100644 (file)
index 0000000..179d7aa
--- /dev/null
@@ -0,0 +1,98 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_PacketSocketHandle_
+#define HH_PacketSocketHandle_ 1
+
+// Custom includes
+#include "SocketPolicy.hh"
+#include "SocketProtocol.hh"
+#include "ProtocolClientSocketHandle.hh"
+#include "LLAddressing.hh"
+#include "FramingPolicy.hh"
+#include "CommunicationPolicy.hh"
+#include "ReadWritePolicy.hh"
+#include "BufferingPolicy.hh"
+#include "BSDSocketProtocol.hh"
+
+//#include "PacketSocketHandle.mpp"
+#include "PacketSocketHandle.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+    
+    typedef MakeSocketPolicy<
+        LLAddressingPolicy,
+        DatagramFramingPolicy,
+        UnconnectedCommunicationPolicy,
+        ReadablePolicy,
+        WriteablePolicy,
+        SocketBufferingPolicy
+        >::policy Packet_Policy;
+
+    class PacketProtocol 
+        : public ConcreteSocketProtocol<Packet_Policy>,
+          public BSDSocketProtocol
+    {
+    public:
+        enum SocketType { RawSocket, DatagramSocket };
+
+        void init_client(SocketType type = RawSocket, int protocol = -1) const;
+
+        std::auto_ptr<SocketProtocol> clone() const;
+
+        enum PromiscMode { Promiscuous, AllMulticast, None };
+
+        void promisc(std::string interface, PromiscMode mode) const;
+        // See LLSocketAddress for a discussion/rationale for
+        // ForwardRange here
+        template <class ForwardRange>
+        void mcAdd(std::string interface, ForwardRange const & address) const;
+        template <class ForwardRange>
+        void mcDrop(std::string interface, ForwardRange const & address) const;
+
+        unsigned available() const;
+        bool eof() const;
+
+    private:
+        template<class ForwardRange>
+        void do_mc(std::string interface, ForwardRange const & address, bool add) const;
+        void do_mc_i(std::string interface, detail::LLAddressCopier const & copier, bool add) const;
+    };
+
+    typedef ProtocolClientSocketHandle<PacketProtocol> PacketSocketHandle;
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "PacketSocketHandle.cci"
+#include "PacketSocketHandle.ct"
+#include "PacketSocketHandle.cti"
+//#include "PacketSocketHandle.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/PacketSocketHandle.ih b/Socket/PacketSocketHandle.ih
new file mode 100644 (file)
index 0000000..cc121b0
--- /dev/null
@@ -0,0 +1,60 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_PacketSocketHandle_
+#define IH_PacketSocketHandle_ 1
+
+// Custom includes
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+namespace detail {
+
+    struct LLAddressCopier
+    {
+        virtual ~LLAddressCopier() {}
+        virtual unsigned operator()(unsigned char * target) const = 0;
+    };
+
+    template <class ForwardRange>
+    struct Range_LLAddressCopier
+        : public LLAddressCopier
+    {
+        Range_LLAddressCopier(ForwardRange const & range);
+        
+        unsigned operator()(unsigned char * target) const;
+
+        ForwardRange const & range_;
+    };
+
+}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/PacketSocketHandle.test.cc b/Socket/PacketSocketHandle.test.cc
new file mode 100644 (file)
index 0000000..fb10346
--- /dev/null
@@ -0,0 +1,85 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "PacketSocketHandle.test.hh"
+//#include "PacketSocketHandle.test.ih"
+
+#include "PacketSocketHandle.hh"
+
+// Custom includes
+#include <iostream>
+#include <unistd.h>
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(packetSocketHandle)
+{
+    // We have a Problem here .. packet sockets are only allowed for root
+    if (getuid() != 0) {
+        BOOST_WARN_MESSAGE(false, "Cannot test satcom::lib::PacketSocketHandle as non-root user");
+        return;
+    }
+
+    {
+        satcom::lib::PacketSocketHandle sock;
+        
+        BOOST_CHECK_NO_THROW( sock.bind(satcom::lib::LLSocketAddress("lo")) );
+        satcom::lib::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 ..
+        
+        // TODO: There are some failures here ... need to investigate
+        /*
+        BOOST_CHECK_NO_THROW( sock.protocol().promisc(
+                                  "lo",satcom::lib::PacketProtocol::Promiscuous) );
+        BOOST_CHECK_NO_THROW( sock.protocol().promisc(
+                                  "lo",satcom::lib::PacketProtocol::AllMulticast) );
+        BOOST_CHECK_NO_THROW( sock.protocol().promisc(
+                                  "lo",satcom::lib::PacketProtocol::None) );
+        */
+        
+        BOOST_CHECK_NO_THROW( sock.protocol().mcAdd(
+                                  "lo",satcom::lib::llAddress("01-02-03-04-05-06")) );
+        BOOST_CHECK_NO_THROW( sock.protocol().mcDrop(
+                                  "lo",satcom::lib::llAddress("01-02-03-04-05-06")) );
+
+        BOOST_CHECK_NO_THROW( sock.protocol().available() );
+        BOOST_CHECK( ! sock.eof() );
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ProtocolClientSocketHandle.cti b/Socket/ProtocolClientSocketHandle.cti
new file mode 100644 (file)
index 0000000..0f01b88
--- /dev/null
@@ -0,0 +1,102 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "ProtocolClientSocketHandle.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::ProtocolClientSocketHandle()
+    : ClientSocketHandle<typename SocketProtocol::Policy>(
+        std::auto_ptr<satcom::lib::SocketProtocol>(new SocketProtocol()))
+{
+    this->protocol().init_client();
+}
+
+#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolClientSocketHandle.mpp", 2))
+#include BOOST_PP_ITERATE()
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::
+ProtocolClientSocketHandle(FileHandle other, bool isChecked)
+    : ClientSocketHandle<typename Protocol::Policy>(other, isChecked)
+{}
+
+template <class SocketProtocol>
+prefix_ SocketProtocol const &
+satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::protocol()
+{
+    BOOST_ASSERT( dynamic_cast<SocketProtocol const *>(&this->body().protocol()) );
+    // Need dynamic_cast here, since satcom::lib::SocketProtocol is a
+    // virtual base
+    return dynamic_cast<SocketProtocol const &>(this->body().protocol());
+}
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>
+satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::cast_static(FileHandle handle)
+{
+    return ProtocolClientSocketHandle(handle,true);
+}
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>
+satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::cast_dynamic(FileHandle handle)
+{
+    ClientSocketHandle<typename SocketProtocol::Policy> h(
+        ClientSocketHandle<typename SocketProtocol::Policy>::cast_dynamic(handle));
+    // throw std::bad_cast if the protocol is invalid
+    dynamic_cast<SocketProtocol const &>(static_cast<SocketBody&>(FileHandle::body(h)).protocol());
+    return cast_static(handle);
+}
+
+template <class SocketProtocol>
+prefix_ void
+satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::state(SocketStateMap & map,
+                                                               unsigned lod)
+{
+    map["handle"] = prettyName(typeid(*this));
+    this->body().state(map,lod);
+}
+
+template <class SocketProtocol>
+prefix_ std::string
+satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::dumpState(unsigned lod)
+{
+    SocketStateMap map;
+    state(map,lod);
+    return detail::dumpState(map);
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ProtocolClientSocketHandle.hh b/Socket/ProtocolClientSocketHandle.hh
new file mode 100644 (file)
index 0000000..eeca1e7
--- /dev/null
@@ -0,0 +1,89 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_ProtocolClientSocketHandle_
+#define HH_ProtocolClientSocketHandle_ 1
+
+// Custom includes
+#include "ClientSocketHandle.hh"
+
+#include "ProtocolClientSocketHandle.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    template <class Protocol> class ProtocolServerSocketHandle;
+
+    /** \brief
+      */
+    template <class SocketProtocol>
+    class ProtocolClientSocketHandle
+        : public ClientSocketHandle<typename SocketProtocol::Policy>
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef SocketProtocol Protocol;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        ProtocolClientSocketHandle();
+
+#       define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolClientSocketHandle.mpp", 1))
+#       include BOOST_PP_ITERATE()
+        
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        Protocol const & protocol();
+
+        static ProtocolClientSocketHandle cast_static(FileHandle handle);
+        static ProtocolClientSocketHandle cast_dynamic(FileHandle handle);
+
+        void state(SocketStateMap & map, unsigned lod=0);
+        std::string dumpState(unsigned lod=0);
+
+    protected:
+        ProtocolClientSocketHandle(FileHandle other, bool isChecked);
+
+    private:
+        friend class ProtocolServerSocketHandle<Protocol>;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ProtocolClientSocketHandle.cci"
+//#include "ProtocolClientSocketHandle.ct"
+#include "ProtocolClientSocketHandle.cti"
+#include "ProtocolClientSocketHandle.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ProtocolClientSocketHandle.mpp b/Socket/ProtocolClientSocketHandle.mpp
new file mode 100644 (file)
index 0000000..2804682
--- /dev/null
@@ -0,0 +1,93 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#if !BOOST_PP_IS_ITERATING
+#ifndef MPP_ProtocolClientSocketHandle_
+
+// Custom includes
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/enum.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+//////////////////////////////mpp.p////////////////////////////////////////
+// Local Macros
+
+#define mpp_PCSH_Arg(z,n,data) BOOST_PP_CAT(A,n) const & BOOST_PP_CAT(a,n)
+
+#define mpp_PCSH_TemplateParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A )
+#define mpp_PCSH_MethodParameters() BOOST_PP_ENUM(BOOST_PP_ITERATION(), mpp_PCSH_Arg, )
+#define mpp_PCSH_CallParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a )
+
+//////
+#endif
+#else
+///////////////////////////////////////////////////////////////////////////
+
+//////
+#if BOOST_PP_ITERATION_FLAGS()==1
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::
+// ProtocolClientSocketHandle (constructor) declaration
+
+template < mpp_PCSH_TemplateParameters() >
+ProtocolClientSocketHandle( mpp_PCSH_MethodParameters() );
+
+//////
+#elif BOOST_PP_ITERATION_FLAGS()==2
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::
+// ProtocolClientSocketHandle (constructor) implementation
+
+template <class SocketProtocol>
+template < mpp_PCSH_TemplateParameters() >
+prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::
+ProtocolClientSocketHandle( mpp_PCSH_MethodParameters() )
+    : ClientSocketHandle<typename SocketProtocol::Policy>(
+        std::auto_ptr<satcom::lib::SocketProtocol>(new SocketProtocol()))
+{
+    this->protocol().init_client( mpp_PCSH_CallParameters() );
+}
+
+//////
+#endif
+#endif
+#if !BOOST_PP_IS_ITERATING
+#ifdef MPP_PCSH__ProtocolClientSocketHandle_
+///////////////////////////////////////////////////////////////////////////
+// Undefine local Macros
+
+#undef mpp_PCSH_Arg
+#undef mpp_PCSH_TemplateParameters
+#undef mpp_PCSH_MethodParameters
+#undef mpp_PCSH_CallParameters
+
+//////////////////////////////mpp_PCSH_.e////////////////////////////////////////
+#else
+#define MPP_PCSH__ProtocolClientSocketHandle_ 1
+#endif
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ProtocolClientSocketHandle.test.cc b/Socket/ProtocolClientSocketHandle.test.cc
new file mode 100644 (file)
index 0000000..be924ce
--- /dev/null
@@ -0,0 +1,77 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ProtocolClientSocketHandle.test.hh"
+//#include "ProtocolClientSocketHandle.test.ih"
+
+// Custom includes
+#include "ProtocolClientSocketHandle.hh"
+#include "SocketProtocol.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    struct MyProtocol : public satcom::lib::test::SomeProtocol
+    {
+        using satcom::lib::test::SomeProtocol::init_client;
+        void init_client(char const *,unsigned) const {}
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(protocolClientSocketHandle)
+{
+    typedef satcom::lib::ProtocolClientSocketHandle<MyProtocol> MySocketHandle;
+
+    {
+        typedef satcom::lib::MakeSocketPolicy<
+            satcom::lib::test::SomeFramingPolicy,
+            satcom::lib::test::SomeReadPolicy,
+            satcom::lib::test::SomeWritePolicy
+            >::policy OtherSocketPolicy;
+        typedef satcom::lib::SocketHandle<OtherSocketPolicy> OtherSocketHandle;
+
+        MySocketHandle h;
+        h.protocol();
+        
+        OtherSocketHandle osh (h);
+        h = satcom::lib::static_socket_cast<MySocketHandle>(osh);
+    }
+
+    {
+        MySocketHandle hh("foo.bar.c",1234);
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ProtocolServerSocketHandle.cti b/Socket/ProtocolServerSocketHandle.cti
new file mode 100644 (file)
index 0000000..76bb242
--- /dev/null
@@ -0,0 +1,109 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "ProtocolServerSocketHandle.ih"
+
+// Custom includes
+#include "ProtocolClientSocketHandle.hh"
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::ProtocolServerSocketHandle()
+    : ServerSocketHandle<typename SocketProtocol::Policy>(
+        std::auto_ptr<satcom::lib::SocketProtocol>(new SocketProtocol()))
+{}
+
+#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolServerSocketHandle.mpp", 2))
+#include BOOST_PP_ITERATE()
+
+template <class SocketProtocol>
+prefix_ SocketProtocol const &
+satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::protocol()
+{
+    BOOST_ASSERT( dynamic_cast<SocketProtocol const *>(&this->body().protocol()) );
+    // Need dynamic_cast here, since satcom::lib::SocketProtocol is a
+    // virtual base
+    return dynamic_cast<SocketProtocol const &>(this->body().protocol());
+}
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>
+satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::accept()
+{
+    return ProtocolClientSocketHandle<SocketProtocol>(
+        FileHandle(this->ServerSocketHandle<typename SocketProtocol::Policy>::accept()),true);
+}
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>
+satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::cast_static(FileHandle handle)
+{
+    return ProtocolServerSocketHandle(handle,true);
+}
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>
+satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::cast_dynamic(FileHandle handle)
+{
+    ServerSocketHandle<typename SocketProtocol::Policy> h(
+        ServerSocketHandle<typename SocketProtocol::Policy>::cast_dynamic(handle));
+    // throw std::bad_cast if the protocol is invalid
+    dynamic_cast<SocketProtocol const &>(static_cast<SocketBody&>(FileHandle::body(h)).protocol());
+    return cast_static(handle);
+}
+
+template <class SocketProtocol>
+prefix_ void
+satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::state(SocketStateMap & map,
+                                                               unsigned lod)
+{
+    map["handle"] = prettyName(typeid(*this));
+    this->body().state(map,lod);
+}
+
+template <class SocketProtocol>
+prefix_ std::string
+satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::dumpState(unsigned lod)
+{
+    SocketStateMap map;
+    state(map,lod);
+    return detail::dumpState(map);
+}
+
+template <class SocketProtocol>
+prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::
+ProtocolServerSocketHandle(FileHandle other, bool isChecked)
+    : ServerSocketHandle<typename SocketProtocol::Policy>(other,isChecked)
+{}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ProtocolServerSocketHandle.hh b/Socket/ProtocolServerSocketHandle.hh
new file mode 100644 (file)
index 0000000..c42ee11
--- /dev/null
@@ -0,0 +1,90 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_ProtocolServerSocketHandle_
+#define HH_ProtocolServerSocketHandle_ 1
+
+// Custom includes
+#include "ServerSocketHandle.hh"
+
+#include "ProtocolServerSocketHandle.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+    
+    template <class Protocol> class ProtocolClientSocketHandle;
+
+    /** \brief
+      */
+    template <class SocketProtocol>
+    class ProtocolServerSocketHandle
+        : public ServerSocketHandle<typename SocketProtocol::Policy>
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef SocketProtocol Protocol;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        ProtocolServerSocketHandle();
+
+#       define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolServerSocketHandle.mpp", 1))
+#       include BOOST_PP_ITERATE()
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        Protocol const & protocol();
+
+        ProtocolClientSocketHandle<SocketProtocol> accept();
+
+        static ProtocolServerSocketHandle cast_static(FileHandle handle);
+        static ProtocolServerSocketHandle cast_dynamic(FileHandle handle);
+
+        void state(SocketStateMap & map, unsigned lod=0);
+        std::string dumpState(unsigned lod=0);
+
+    protected:
+        ProtocolServerSocketHandle(FileHandle other, bool isChecked);
+
+    private:
+
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ProtocolServerSocketHandle.cci"
+//#include "ProtocolServerSocketHandle.ct"
+#include "ProtocolServerSocketHandle.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ProtocolServerSocketHandle.mpp b/Socket/ProtocolServerSocketHandle.mpp
new file mode 100644 (file)
index 0000000..029a995
--- /dev/null
@@ -0,0 +1,93 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#if !BOOST_PP_IS_ITERATING
+#ifndef MPP_PSSH__ProtocolServerSocketHandle_
+
+// Custom includes
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/enum.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+//////////////////////////////mpp_PSSH_.p////////////////////////////////////////
+// Local Macros
+
+#define mpp_PSSH_Arg(z,n,data) BOOST_PP_CAT(A,n) const & BOOST_PP_CAT(a,n)
+
+#define mpp_PSSH_TemplateParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A )
+#define mpp_PSSH_MethodParameters() BOOST_PP_ENUM(BOOST_PP_ITERATION(), mpp_PSSH_Arg, )
+#define mpp_PSSH_CallParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a )
+
+//////
+#endif
+#else
+///////////////////////////////////////////////////////////////////////////
+
+//////
+#if BOOST_PP_ITERATION_FLAGS()==1
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::
+// ProtocolServerSocketHandle (constructor) declaration
+
+template < mpp_PSSH_TemplateParameters() >
+ProtocolServerSocketHandle( mpp_PSSH_MethodParameters() );
+
+//////
+#elif BOOST_PP_ITERATION_FLAGS()==2
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::
+// ProtocolServerSocketHandle (constructor) implementation
+
+template <class SocketProtocol>
+template < mpp_PSSH_TemplateParameters() >
+prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::
+ProtocolServerSocketHandle( mpp_PSSH_MethodParameters() )
+    : ServerSocketHandle<typename SocketProtocol::Policy>(
+        std::auto_ptr<satcom::lib::SocketProtocol>(new SocketProtocol()))
+{
+    this->protocol().init_server( mpp_PSSH_CallParameters() );
+}
+
+//////
+#endif
+#endif
+#if !BOOST_PP_IS_ITERATING
+#ifdef MPP_PSSH__ProtocolServerSocketHandle_
+///////////////////////////////////////////////////////////////////////////
+// Undefine local Macros
+
+#undef mpp_PSSH_Arg
+#undef mpp_PSSH_TemplateParameters
+#undef mpp_PSSH_MethodParameters
+#undef mpp_PSSH_CallParameters
+
+//////////////////////////////mpp_PSSH_.e////////////////////////////////////////
+#else
+#define MPP_PSSH__ProtocolServerSocketHandle_ 1
+#endif
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ProtocolServerSocketHandle.test.cc b/Socket/ProtocolServerSocketHandle.test.cc
new file mode 100644 (file)
index 0000000..22b6cb4
--- /dev/null
@@ -0,0 +1,90 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ProtocolServerSocketHandle.test.hh"
+//#include "ProtocolServerSocketHandle.test.ih"
+
+// Custom includes
+#include "ProtocolServerSocketHandle.hh"
+#include "SocketProtocol.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+
+    struct MyProtocol : public satcom::lib::test::SomeProtocol
+    {
+        using satcom::lib::test::SomeProtocol::init_server;
+        void init_server(char const *,unsigned) const {}
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(protocolServerSocketHandle)
+{
+    typedef satcom::lib::ProtocolServerSocketHandle<MyProtocol> MySocketHandle;
+
+    {
+        typedef satcom::lib::MakeSocketPolicy<
+            satcom::lib::test::SomeFramingPolicy,
+            satcom::lib::test::SomeReadPolicy,
+            satcom::lib::test::SomeWritePolicy
+            >::policy OtherSocketPolicy;
+        typedef satcom::lib::SocketHandle<OtherSocketPolicy> OtherSocketHandle;
+
+        MySocketHandle h;
+        h.protocol();
+
+        OtherSocketHandle osh (h);
+        h = satcom::lib::static_socket_cast<MySocketHandle>(osh);
+   
+        MySocketHandle::ClientSocketHandle client = h.accept();
+        BOOST_CHECK_EQUAL( client.fd(), -1 );
+
+        BOOST_CHECK_EQUAL( h.dumpState(),
+                           "handle: satcom::lib::ProtocolServerSocketHandle<(anonymous namespace)::MyProtocol>\n"
+                           "file.handle: -1\n"
+                           "file.refcount: 2\n"
+                           "socket.policy: satcom::lib::SocketPolicy<satcom::lib::test::SomeAddressingPolicy, satcom::lib::test::SomeFramingPolicy, satcom::lib::test::SomeCommunicationPolicy, satcom::lib::test::SomeReadPolicy, satcom::lib::test::SomeWritePolicy, satcom::lib::test::SomeBufferingPolicy>\n"
+                           "socket.protocol: (anonymous namespace)::MyProtocol\n"
+                           "socket.server: true\n" );
+
+    }
+
+    {
+        MySocketHandle h("foo.bar.c",1234);
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ReadWritePolicy.cc b/Socket/ReadWritePolicy.cc
new file mode 100644 (file)
index 0000000..4f772e4
--- /dev/null
@@ -0,0 +1,130 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "ReadWritePolicy.hh"
+//#include "ReadWritePolicy.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+//#include "ReadWritePolicy.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ unsigned satcom::lib::ReadablePolicy::read(FileHandle handle, char * buffer,
+                                                   unsigned size)
+{
+    int rv = -1;
+    do {
+        rv = ::read(handle.fd(), buffer, size);
+        if (rv < 0)
+            switch(errno) {
+            case EINTR:
+                break;
+            case EAGAIN:
+                // This means, the socket is non-blocking an no data was available
+                rv = 0;
+                break;
+            default:
+                throw SystemException(errno);
+            }
+    } while (rv<0);
+    return rv;
+}
+
+prefix_ unsigned satcom::lib::ReadablePolicy::do_readfrom(FileHandle handle, char * buffer,
+                                                          unsigned size,
+                                                          struct ::sockaddr * addr, socklen_t len)
+{
+    int rv = -1;
+    do {
+        rv = ::recvfrom(handle.fd(),buffer, size, 0, addr, &len);
+        if (rv < 0)
+            switch (errno) {
+            case EINTR:
+                break;
+            case EAGAIN:
+                rv = 0;
+                break;
+            default:
+                throw SystemException(errno);
+            }
+    } while (rv<0);
+    return rv;
+}
+
+prefix_ unsigned satcom::lib::WriteablePolicy::do_write(FileHandle handle, char const * buffer,
+                                                        unsigned size)
+{
+    int rv = -1;
+    do {
+        rv = ::write(handle.fd(), buffer, size);
+        if (rv < 0)
+            switch (errno) {
+            case EINTR:
+                break;
+            case EAGAIN:
+                rv = 0;
+                break;
+            default:
+                throw SystemException(errno);
+            }
+    } while (rv<0);
+    return rv;
+}
+
+prefix_ unsigned satcom::lib::WriteablePolicy::do_writeto(FileHandle handle,
+                                                          char const * buffer, unsigned size,
+                                                          struct sockaddr * addr, socklen_t len)
+{
+    int rv = -1;
+    do {
+        rv = ::sendto(handle.fd(), buffer, size, 0, addr, len);
+        if (rv < 0)
+            switch (errno) {
+            case EINTR:
+                break;
+            case EAGAIN:
+                rv = 0;
+                break;
+            default:
+                throw SystemException(errno);
+            }
+    } while (rv<0);
+    return rv;
+}
+    
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "ReadWritePolicy.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ReadWritePolicy.cti b/Socket/ReadWritePolicy.cti
new file mode 100644 (file)
index 0000000..f4f7f84
--- /dev/null
@@ -0,0 +1,66 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "ReadWritePolicy.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Policy>
+prefix_ unsigned satcom::lib::ReadablePolicy::
+readfrom(ClientSocketHandle<Policy> handle, char * buffer, unsigned size,
+         typename Policy::AddressingPolicy::Address & address,
+         typename IfCommunicationPolicyIs<Policy,UnconnectedCommunicationPolicy>::type *)
+{
+    return do_rcvfrom(handle, buffer, size, address.sockaddr_p(), address.sockaddr_len());
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::WriteablePolicy::
+write(ClientSocketHandle<Policy> handle, char const * buffer, unsigned size,
+      typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type *)
+{
+    return do_write(handle,buffer,size);
+}
+
+template <class Policy>
+prefix_ unsigned satcom::lib::WriteablePolicy::
+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 *)
+{
+    return do_writeto(handle, buffer, size, addr.sockaddr_p(), addr.sockaddr_len());
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ReadWritePolicy.hh b/Socket/ReadWritePolicy.hh
new file mode 100644 (file)
index 0000000..fa49481
--- /dev/null
@@ -0,0 +1,90 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_ReadWritePolicy_
+#define HH_ReadWritePolicy_ 1
+
+// Custom includes
+#include "SocketPolicy.hh"
+#include "ClientSocketHandle.hh"
+#include "CommunicationPolicy.hh" 
+
+//#include "ReadWritePolicy.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+// TODO: ReadWritePolicy.test.cc ...
+
+struct sockaddr;
+
+namespace satcom {
+namespace lib {
+
+    struct ReadablePolicy : public ReadPolicyBase
+    {
+        static unsigned read(FileHandle handle, char * buffer, unsigned size);
+        template <class Policy>
+        static unsigned readfrom(ClientSocketHandle<Policy> handle, char * buffer, unsigned size,
+                                 typename Policy::AddressingPolicy::Address & address,
+                                 typename IfCommunicationPolicyIs<Policy,UnconnectedCommunicationPolicy>::type * = 0);
+
+    private:
+        static unsigned do_readfrom(FileHandle handle, char * buffer, unsigned size,
+                                    struct ::sockaddr * addr, socklen_t len);
+    };
+
+    struct NotReadablePolicy : public ReadPolicyBase
+    {};
+
+    struct WriteablePolicy : public WritePolicyBase
+    {
+        template <class Policy>
+        static unsigned write(ClientSocketHandle<Policy> handle, char const * buffer, unsigned size,
+                              typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0);
+        template <class Policy>
+        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);
+
+    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);
+    };
+    
+    struct NotWriteablePolicy : public WritePolicyBase
+    {};
+
+}}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ReadWritePolicy.cci"
+//#include "ReadWritePolicy.ct"
+#include "ReadWritePolicy.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SConscript b/Socket/SConscript
new file mode 100644 (file)
index 0000000..1375a71
--- /dev/null
@@ -0,0 +1,15 @@
+Import('env')
+import SatSCons
+
+###########################################################################
+
+sources = SatSCons.GlobSources()
+
+SatSCons.StandardTargets(env)
+
+SatSCons.Lib(env,
+             library = 'Socket',
+             sources = sources,
+             LIBS = [ 'Utils' ])
+
+SatSCons.Doxygen(env,sources)
diff --git a/Socket/ServerSocketHandle.cti b/Socket/ServerSocketHandle.cti
new file mode 100644 (file)
index 0000000..0887c90
--- /dev/null
@@ -0,0 +1,160 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "ServerSocketHandle.ih"
+
+// Custom includes
+#include <typeinfo>
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class SocketPolicy>
+template <class OtherPolicy>
+prefix_ satcom::lib::ServerSocketHandle<SocketPolicy>::
+ServerSocketHandle(ServerSocketHandle<OtherPolicy> other,
+                   typename SocketHandle<SocketPolicy>::template IsCompatible<OtherPolicy>::type *)
+    : SocketHandle<SocketPolicy>(other,true)
+{}
+
+template <class SocketPolicy>
+prefix_  satcom::lib::ServerSocketHandle<SocketPolicy>::
+ServerSocketHandle(std::auto_ptr<SocketProtocol> protocol)
+    : SocketHandle<SocketPolicy>(protocol,true)
+{}
+
+template <class SocketPolicy>
+template <class OtherPolicy>
+prefix_ typename satcom::lib::SocketHandle<SocketPolicy>::template IsCompatible<OtherPolicy>::type const &
+satcom::lib::ServerSocketHandle<SocketPolicy>::operator=(ServerSocketHandle<OtherPolicy> other)
+{
+    assign(other);
+    return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Server socket interface
+
+template <class Policy>
+prefix_ void satcom::lib::ServerSocketHandle<Policy>::bind(AddressParam addr)
+{
+    Policy::AddressingPolicy::bind(*this,addr);
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ServerSocketHandle<Policy>::listen(unsigned backlog)
+{
+    Policy::CommunicationPolicy::listen(*this,backlog);
+}
+
+template <class Policy>
+prefix_ typename satcom::lib::ServerSocketHandle<Policy>::Address
+satcom::lib::ServerSocketHandle<Policy>::local()
+{
+    typename Policy::AddressingPolicy::Address addr;
+    this->local(addr);
+    return addr;
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ServerSocketHandle<Policy>::local(Address & addr)
+{
+    Policy::AddressingPolicy::local(*this,addr);
+}
+
+template <class Policy>
+prefix_ typename satcom::lib::ServerSocketHandle<Policy>::ClientSocketHandle
+satcom::lib::ServerSocketHandle<Policy>::accept()
+{
+    Address address;
+    return acceptfrom(address);
+}
+
+template <class Policy>
+prefix_ std::pair<typename satcom::lib::ServerSocketHandle<Policy>::ClientSocketHandle,
+                  typename satcom::lib::ServerSocketHandle<Policy>::Address>
+satcom::lib::ServerSocketHandle<Policy>::acceptfrom()
+{
+
+    Address address;
+    ClientSocketHandle handle = accept(address);
+    return std::make_pair(handle,address);
+}
+
+template <class Policy>
+prefix_ typename satcom::lib::ServerSocketHandle<Policy>::ClientSocketHandle
+satcom::lib::ServerSocketHandle<Policy>::acceptfrom(Address & addr)
+{
+    return ClientSocketHandle(this->protocol().clone(), 
+                              Policy::CommunicationPolicy::accept(*this,addr));
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+template <class Policy>
+prefix_ satcom::lib::ServerSocketHandle<Policy>::ServerSocketHandle(FileHandle other,
+                                                                    bool isChecked)
+    : SocketHandle<Policy>(other, isChecked)
+{}
+
+template <class Policy>
+prefix_ satcom::lib::ServerSocketHandle<Policy>
+satcom::lib::ServerSocketHandle<Policy>::cast_static(FileHandle handle)
+{
+    return ServerSocketHandle(handle,true);
+}
+
+template <class Policy>
+prefix_ satcom::lib::ServerSocketHandle<Policy>
+satcom::lib::ServerSocketHandle<Policy>::cast_dynamic(FileHandle handle)
+{
+    SocketHandle<Policy> h (SocketHandle<Policy>::cast_dynamic(handle));
+    if (! static_cast<SocketBody&>(FileHandle::body(handle)).isServer())
+        throw std::bad_cast();
+    return cast_static(handle);
+}
+
+template <class Policy>
+prefix_ void satcom::lib::ServerSocketHandle<Policy>::state(SocketStateMap & map, unsigned lod)
+{
+    map["handle"] = prettyName(typeid(*this));
+    this->body().state(map,lod);
+}
+
+template <class Policy>
+prefix_ std::string satcom::lib::ServerSocketHandle<Policy>::dumpState(unsigned lod)
+{
+    SocketStateMap map;
+    state(map,lod);
+    return detail::dumpState(map);
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ServerSocketHandle.hh b/Socket/ServerSocketHandle.hh
new file mode 100644 (file)
index 0000000..42a6bae
--- /dev/null
@@ -0,0 +1,125 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_ServerSocketHandle_
+#define HH_ServerSocketHandle_ 1
+
+// Custom includes
+#include <boost/static_assert.hpp>
+#include <boost/call_traits.hpp>
+#include "SocketHandle.hh"
+#include "CommunicationPolicy.hh"
+#include "AddressingPolicy.hh"
+
+//#include "ServerSocketHandle.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    template <class Policy> class ClientSocketHandle;
+
+    /** \brief
+      */
+    template <class Policy>
+    class ServerSocketHandle
+        : public SocketHandle<Policy>
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef typename Policy::AddressingPolicy::Address Address;
+        typedef typename boost::call_traits<Address>::param_type AddressParam;
+        typedef ClientSocketHandle<Policy> ClientSocketHandle;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        // no default constructor
+        // default copy constructor
+        // default copy assignment
+        // default destructor
+
+        // conversion constructors
+        template <class OtherPolicy>
+        ServerSocketHandle(ServerSocketHandle<OtherPolicy> other,
+                           typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type * = 0);
+
+        template <class OtherPolicy>
+        typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const & 
+        operator=(ServerSocketHandle<OtherPolicy> other);
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Server socket interface
+        ///@{
+
+        void         bind         (AddressParam addr);
+        void         listen       (unsigned backlog=0);
+
+        Address      local        ();
+        void         local        (Address & addr);
+
+        // 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()
+        ClientSocketHandle 
+                     accept       ();
+        std::pair<ClientSocketHandle, Address>
+                     acceptfrom   ();
+        ClientSocketHandle
+                     acceptfrom   (Address & addr);
+        
+        ///@}
+
+        static ServerSocketHandle cast_static(FileHandle handle);
+        static ServerSocketHandle 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);
+
+    protected:
+        ServerSocketHandle(FileHandle other, bool isChecked);
+        explicit ServerSocketHandle(std::auto_ptr<SocketProtocol> protocol);
+
+    private:
+        
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ServerSocketHandle.cci"
+//#include "ServerSocketHandle.ct"
+#include "ServerSocketHandle.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/ServerSocketHandle.test.cc b/Socket/ServerSocketHandle.test.cc
new file mode 100644 (file)
index 0000000..299524f
--- /dev/null
@@ -0,0 +1,101 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "ServerSocketHandle.test.hh"
+//#include "ServerSocketHandle.test.ih"
+
+// Custom includes
+#include "ServerSocketHandle.hh"
+#include "ClientSocketHandle.hh"
+#include "SocketProtocol.test.hh"
+#include "AddressingPolicy.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    
+    namespace sl = satcom::lib;
+    
+    class MySocketHandle
+        : public sl::ServerSocketHandle<sl::test::SomeProtocol::Policy>
+    {
+    public:
+        MySocketHandle()
+            : sl::ServerSocketHandle<sl::test::SomeProtocol::Policy>(
+                std::auto_ptr<sl::SocketProtocol>(new sl::test::SomeProtocol()))
+            {}
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(serverSocketHandle)
+{
+    typedef sl::MakeSocketPolicy<
+        sl::test::SomeFramingPolicy,
+        sl::test::SomeReadPolicy,
+        sl::test::SomeWritePolicy
+        >::policy OtherSocketPolicy;
+    typedef sl::SocketHandle<OtherSocketPolicy> OtherSocketHandle;
+    
+    MySocketHandle myh;
+    OtherSocketHandle osh (myh);
+    osh = myh;
+
+    typedef sl::ServerSocketHandle<sl::test::SomeProtocol::Policy> SomeSocketHandle;
+    SomeSocketHandle ssh = sl::static_socket_cast<SomeSocketHandle>(osh);
+
+    typedef sl::ServerSocketHandle<sl::MakeSocketPolicy<
+        OtherSocketPolicy,
+        satcom::lib::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 );
+    BOOST_CHECK_THROW( sl::dynamic_socket_cast<OtherClientHandle>(osh),
+                       std::bad_cast );
+
+    BOOST_CHECK_NO_THROW( myh.bind(0) );
+    BOOST_CHECK_EQUAL( myh.local(), 2u );
+
+    {
+        MySocketHandle::ClientSocketHandle client = myh.accept();
+        BOOST_CHECK_EQUAL( client.fd(), -1 );
+    }
+    
+}
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketHandle.cc b/Socket/SocketHandle.cc
new file mode 100644 (file)
index 0000000..186953a
--- /dev/null
@@ -0,0 +1,146 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "SocketHandle.hh"
+#include "SocketHandle.ih"
+
+// Custom includes
+#include <sstream>
+#include <sys/socket.h>
+#include "Utils/TypeInfo.hh"
+
+//#include "SocketHandle.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void satcom::lib::SocketBody::v_close()
+{
+    if (::shutdown(fd(),SHUT_RDWR) < 0)
+        throw SystemException(errno);
+    if (::close(fd()) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void satcom::lib::SocketBody::v_terminate()
+{
+    struct linger ling;
+    ling.l_onoff = 0;
+    ling.l_linger = 0;
+
+    // We purposely IGNORE any errors: this method is used to try and
+    // terminate the connection ignoring any possible problems
+
+    ::setsockopt(fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling));
+    ::shutdown(fd(),SHUT_RDWR);
+    ::close(fd());
+}
+
+prefix_ bool satcom::lib::SocketBody::v_eof()
+    const
+{
+    return protocol().eof();
+}
+
+prefix_ void satcom::lib::SocketBody::state(SocketStateMap & map, unsigned lod)
+{
+    map["file.handle"] = fd();
+    map["file.refcount"] = refcount();
+    map["socket.server"] = isServer();
+    map["socket.protocol"] = prettyName(typeid(protocol()));
+    map["socket.policy"] = prettyName(typeid(protocol().policy()));
+    protocol().state(map,lod);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::detail::StateMapOrdering
+
+namespace {
+    bool contains(std::string::iterator b, std::string::iterator e, char c)
+    {
+        for (; b != e; ++b)
+            if (*b == c)
+                return true;
+        return false;
+    }
+}
+
+prefix_ bool satcom::lib::detail::StateMapOrdering::operator()(std::string a1, std::string a2)
+    const
+{
+    std::string::iterator i1 (a1.begin());
+    std::string::iterator const i1_end (a1.end());
+    std::string::iterator i2 (a2.begin());
+    std::string::iterator const i2_end (a2.end());
+    for(; i1 != i1_end && i2 != i2_end && *i1 == *i2; ++i1, ++i2) ;
+    if (i1 == i1_end) {
+        if (i2 == i2_end)
+            // the strings are equal
+            return false;
+        if (contains(i2,i2_end,'.'))
+            // the longer string is a sub-'directory' of the shorter
+            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
+            return false;
+        return *i1 < *i2;
+    }
+    if (contains(i1,i1_end,'.')) {
+        if (contains(i2,i2_end,'.'))
+            return *i1 < *i2;
+        return false;
+    }
+    else if (contains(i2,i2_end,'.'))
+        return true;
+    return *i1 < *i2;
+}
+
+prefix_ std::string satcom::lib::detail::dumpState(SocketStateMap const & map)
+{
+    std::stringstream s;
+    SocketStateMap::const_iterator i (map.begin());
+    SocketStateMap::const_iterator i_end (map.end());
+    for (; i != i_end; ++i)
+        s << i->first << ": " << i->second << "\n";
+    return s.str();
+}
+
+template <class Policy>
+prefix_ std::ostream & satcom::lib::operator<<(std::ostream & os, SocketHandle<Policy> handle)
+{
+    os << handle.dumpState();
+    return os;
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "SocketHandle.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketHandle.cci b/Socket/SocketHandle.cci
new file mode 100644 (file)
index 0000000..f036df1
--- /dev/null
@@ -0,0 +1,78 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+#include "SocketHandle.ih"
+
+// Custom includes
+#include "Utils/Exception.hh"
+#include "SocketProtocol.hh"
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ satcom::lib::SocketBody::SocketBody(std::auto_ptr<SocketProtocol> protocol,
+                                            bool isServer)
+    : protocol_(protocol), isServer_(isServer)
+{
+    BOOST_ASSERT( ! protocol_->body_ );
+    protocol_->body_ = this;
+}
+
+prefix_ satcom::lib::SocketBody::SocketBody(std::auto_ptr<SocketProtocol> protocol,
+                                            bool isServer, int fd)
+    : FileBody(fd), protocol_(protocol), isServer_(isServer)
+{
+    BOOST_ASSERT( ! protocol_->body_ );
+    protocol_->body_ = this;
+}
+
+prefix_ satcom::lib::SocketProtocol const & satcom::lib::SocketBody::protocol()
+    const
+{
+    return *protocol_;
+}
+
+prefix_ bool satcom::lib::SocketBody::isServer()
+{
+    return isServer_;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::detail::ConvertibleString
+
+prefix_ satcom::lib::detail::ConvertibleString::ConvertibleString()
+{}
+
+prefix_ satcom::lib::detail::ConvertibleString::ConvertibleString(bool v)
+    : std::string(v ? "true" : "false")
+{}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketHandle.ct b/Socket/SocketHandle.ct
new file mode 100644 (file)
index 0000000..9a90bd8
--- /dev/null
@@ -0,0 +1,50 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+#include "SocketHandle.ih"
+
+// Custom includes
+#include <boost/lexical_cast.hpp>
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class T>
+prefix_ satcom::lib::detail::ConvertibleString &
+satcom::lib::detail::ConvertibleString::operator+=(ConvertibleString const & other)
+{
+    if (!empty())
+        this->std::string::operator+=(", ");
+    this->std::string::operator+=(other);
+    return *this;
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketHandle.cti b/Socket/SocketHandle.cti
new file mode 100644 (file)
index 0000000..dde5bf7
--- /dev/null
@@ -0,0 +1,188 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+#include "SocketHandle.ih"
+
+// Custom includes
+#include <typeinfo>
+#include <boost/lexical_cast.hpp>
+#include "Utils/TypeInfo.hh"
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class SocketPolicy>
+template <class OtherPolicy>
+prefix_ satcom::lib::SocketHandle<SocketPolicy>::SocketHandle(SocketHandle<OtherPolicy> other,
+                                                              typename IsCompatible<OtherPolicy>::type *)
+    : FileHandle(other)
+{}
+
+template <class SocketPolicy>
+template <class OtherPolicy>
+prefix_ typename satcom::lib::SocketHandle<SocketPolicy>::template IsCompatible<OtherPolicy>::type const &
+satcom::lib::SocketHandle<SocketPolicy>::operator=(SocketHandle<OtherPolicy> other)
+{
+    assign(other);
+    return *this;
+}
+
+template <class SocketPolicy>
+prefix_ 
+satcom::lib::SocketHandle<SocketPolicy>::SocketHandle(std::auto_ptr<SocketProtocol> protocol,
+                                                      bool isServer)
+    : FileHandle(std::auto_ptr<FileBody>(new SocketBody(protocol,isServer)))
+{}
+
+template <class SocketPolicy>
+prefix_ satcom::lib::SocketHandle<SocketPolicy>::SocketHandle(FileHandle other, bool isChecked)
+    : FileHandle(other)
+{
+    BOOST_ASSERT( isChecked );
+    BOOST_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
+}
+
+template <class SocketPolicy>
+prefix_ satcom::lib::SocketBody & satcom::lib::SocketHandle<SocketPolicy>::body()
+{
+    BOOST_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()) );
+    return static_cast<SocketBody &>(FileHandle::body());
+}
+
+template <class SocketPolicy>
+prefix_ satcom::lib::SocketBody const & satcom::lib::SocketHandle<SocketPolicy>::body()
+    const
+{
+    BOOST_ASSERT( dynamic_cast<SocketBody const *>(&FileHandle::body()) );
+    return static_cast<SocketBody const &>(FileHandle::body());
+}
+
+template <class SocketPolicy>
+prefix_ satcom::lib::SocketProtocol const & satcom::lib::SocketHandle<SocketPolicy>::protocol()
+    const
+{
+    return body().protocol();
+}
+
+template <class SocketPolicy>
+prefix_ void satcom::lib::SocketHandle<SocketPolicy>::assign(FileHandle other)
+{
+    FileHandle::operator=(other);
+}
+
+template <class SocketPolicy>
+prefix_ satcom::lib::SocketHandle<SocketPolicy>
+satcom::lib::SocketHandle<SocketPolicy>::cast_static(FileHandle handle)
+{
+    return SocketHandle(handle,true);
+}
+
+template <class SocketPolicy>
+prefix_ satcom::lib::SocketHandle<SocketPolicy>
+satcom::lib::SocketHandle<SocketPolicy>::cast_dynamic(FileHandle handle)
+{
+    // throws bad_cast if the body is not a SocketBody
+    SocketBody & body (dynamic_cast<SocketBody&>(FileHandle::body(handle)));
+    // throws bad_cast if the poplicy is not compatible
+    SocketPolicy::checkBaseOf(body.protocol().policy());
+    return cast_static(handle);
+}
+
+template <class Target, class Source>
+prefix_ Target satcom::lib::static_socket_cast(Source handle)
+{
+    BOOST_STATIC_ASSERT((
+        boost::is_convertible<Source*,FileHandle*>::value &&
+        boost::is_convertible<Target*,FileHandle*>::value &&
+        ( boost::is_convertible<Source,Target>::value ||
+          boost::is_convertible<Target,Source>::value ) ));
+    BOOST_ASSERT( check_socket_cast<Target>(handle) );
+    return Target::cast_static(handle);
+}
+
+template <class Target, class Source>
+prefix_ Target satcom::lib::dynamic_socket_cast(Source handle)
+{
+    BOOST_STATIC_ASSERT((
+        boost::is_convertible<Source*,FileHandle*>::value &&
+        boost::is_convertible<Target*,FileHandle*>::value &&
+        ( boost::is_convertible<Source,Target>::value ||
+          boost::is_convertible<Target,Source>::value ) ));
+    return Target::cast_dynamic(handle);
+}
+
+template <class Target, class Source>
+prefix_ bool satcom::lib::check_socket_cast(Source handle)
+{
+    BOOST_STATIC_ASSERT((
+        boost::is_convertible<Source*,FileHandle*>::value &&
+        boost::is_convertible<Target*,FileHandle*>::value &&
+        ( boost::is_convertible<Source,Target>::value ||
+          boost::is_convertible<Target,Source>::value ) ));
+    // we don't have a non-throwing variant of cast_dynamic
+    // for two reasons:
+    // a) since the handle is passed back by value, we cannot return
+    //    something like a null handle
+    // b) it is simpler to implement cast_dynamic throwig bad_cast on
+    //    failure than implementing cast_check
+    try {
+        Target::cast_dynamic(handle);
+    }
+    catch (std::bad_cast const &) {
+        return false;
+    }
+    return true;
+}
+
+template <class SocketPolicy>
+prefix_ void satcom::lib::SocketHandle<SocketPolicy>::state(SocketStateMap & map, unsigned lod)
+{
+    map["handle"] = prettyName(typeid(*this));
+    body().state(map,lod);
+}
+
+template <class SocketPolicy>
+prefix_ std::string satcom::lib::SocketHandle<SocketPolicy>::dumpState(unsigned lod)
+{
+    SocketStateMap map;
+    state(map,lod);
+    return detail::dumpState(map);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// satcom::lib::detail::ConvertibleString
+
+template <class T>
+prefix_ satcom::lib::detail::ConvertibleString::ConvertibleString(T const & other)
+    : std::string(boost::lexical_cast<std::string>(other))
+{}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketHandle.hh b/Socket/SocketHandle.hh
new file mode 100644 (file)
index 0000000..f56e7d4
--- /dev/null
@@ -0,0 +1,122 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// TODO: Create a SocketHandleBase class and move some non-Policy
+// dependent code there
+
+#ifndef HH_SocketHandle_
+#define HH_SocketHandle_ 1
+
+// Custom includes
+#include <memory> // std::auto_ptr
+#include "FileHandle.hh"
+#include "SocketPolicy.hh"
+
+//#include "SocketHandle.mpp"
+#include "SocketHandle.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+#include "SocketHandle.ih"
+
+namespace satcom {
+namespace lib {
+
+    /** \brief
+      */
+    template <class SocketPolicy>
+    class SocketHandle
+        : public FileHandle
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef SocketPolicy Policy;
+
+        template <class OtherPolicy>
+        struct IsCompatible
+            : public boost::enable_if< SocketPolicyIsBaseOf<SocketPolicy,OtherPolicy>,
+                                       SocketHandle >
+        {};
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        // default copy constructor
+        // default copy assignment
+        // default destructor
+
+        // conversion constructors
+        template <class OtherPolicy>
+        SocketHandle(SocketHandle<OtherPolicy> other, 
+                     typename IsCompatible<OtherPolicy>::type * = 0);
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        template <class OtherPolicy>
+        typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
+
+        static SocketHandle cast_static(FileHandle handle);
+        static SocketHandle cast_dynamic(FileHandle handle);
+
+        void state(SocketStateMap & map, unsigned lod=0);
+        std::string dumpState(unsigned lod=0);
+
+    protected:
+        explicit SocketHandle(std::auto_ptr<SocketProtocol> protocol, bool isServer);
+        SocketHandle(FileHandle other, bool isChecked);
+        
+        SocketBody & body();
+        SocketBody const & body() const;
+        SocketProtocol const & protocol() const;
+
+        void assign(FileHandle other);
+
+    private:
+
+    };
+
+    template <class Policy>
+    std::ostream & operator<<(std::ostream & os, SocketHandle<Policy> handle);
+
+    template <class Target, class Source>
+    Target static_socket_cast(Source handle);
+
+    template <class Target, class Source>
+    Target dynamic_socket_cast(Source handle);
+
+    template <class Target, class Source>
+    bool check_socket_cast(Source handle);
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "SocketHandle.cci"
+#include "SocketHandle.ct"
+#include "SocketHandle.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketHandle.ih b/Socket/SocketHandle.ih
new file mode 100644 (file)
index 0000000..f2e2a32
--- /dev/null
@@ -0,0 +1,111 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_SocketHandle_
+#define IH_SocketHandle_ 1
+
+// Custom includes
+#include <map>
+#include <string>
+#include <boost/scoped_ptr.hpp>
+#include "FileHandle.hh"
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    class SocketProtocol;
+
+    namespace detail {
+
+        class ConvertibleString : public std::string
+        {
+        public:
+            ConvertibleString();
+            ConvertibleString(bool v);
+            template <class T>
+            ConvertibleString(T const & other);
+            template <class T>
+            ConvertibleString & operator+= (ConvertibleString const & other);
+        };
+        
+        struct StateMapOrdering
+            : public std::binary_function<std::string,std::string,bool>
+        {
+            bool operator()(std::string a1, std::string a2) const;
+        };
+        
+    }
+
+    typedef std::map< std::string, detail::ConvertibleString, detail::StateMapOrdering > SocketStateMap;
+
+    namespace detail {
+        std::string dumpState(SocketStateMap const & map);
+    }
+
+    class SocketBody
+        : public FileBody
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+        
+        typedef boost::intrusive_ptr<SocketBody> ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        explicit SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
+        SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
+
+        // no copy
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        SocketProtocol const & protocol() const;
+        bool isServer();
+        
+        void state(SocketStateMap & map, unsigned lod);
+
+    private:
+        virtual void v_close();
+        virtual void v_terminate();
+        virtual bool v_eof() const;
+
+        boost::scoped_ptr<SocketProtocol> protocol_;
+        bool isServer_;
+    };
+
+}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketHandle.test.cc b/Socket/SocketHandle.test.cc
new file mode 100644 (file)
index 0000000..cc2def8
--- /dev/null
@@ -0,0 +1,107 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "SocketHandle.test.hh"
+//#include "SocketHandle.test.ih"
+
+// Custom includes
+#include "SocketHandle.hh"
+#include "SocketProtocol.test.hh"
+#include "AddressingPolicy.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    namespace sl = satcom::lib;
+
+    class MySocketHandle
+        : public sl::SocketHandle<sl::test::SomeProtocol::Policy>
+    {
+    public:
+        MySocketHandle()
+            : sl::SocketHandle<sl::test::SomeProtocol::Policy>(
+                std::auto_ptr<sl::SocketProtocol>(new sl::test::SomeProtocol()),false)
+            {}
+    };
+
+    class FDHandle
+        : public satcom::lib::FileHandle
+    {
+    public:
+        FDHandle() 
+            : satcom::lib::FileHandle(std::auto_ptr<satcom::lib::FileBody>(
+                                          new satcom::lib::FileBody())) {}
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(socketHandle)
+{
+    typedef sl::MakeSocketPolicy<
+        sl::test::SomeCommunicationPolicy,
+        sl::test::SomeReadPolicy
+        >::policy OtherSocketPolicy;
+    typedef sl::SocketHandle<OtherSocketPolicy> OtherSocketHandle;
+    
+    MySocketHandle myh;
+    OtherSocketHandle osh (myh);
+    osh = myh;
+
+    typedef sl::SocketHandle<sl::test::SomeProtocol::Policy> SomeSocketHandle;
+    SomeSocketHandle ssh = satcom::lib::static_socket_cast<SomeSocketHandle>(osh);
+
+    BOOST_CHECK_NO_THROW( satcom::lib::dynamic_socket_cast<SomeSocketHandle>(osh) );
+
+    typedef sl::SocketHandle< sl::MakeSocketPolicy<
+        OtherSocketPolicy,
+        satcom::lib::NoAddressingPolicy
+        >::policy> SomeOtherSocketHandle;
+
+    BOOST_CHECK_THROW( satcom::lib::dynamic_socket_cast<SomeOtherSocketHandle>(osh), 
+                       std::bad_cast );
+    BOOST_CHECK_THROW( satcom::lib::dynamic_socket_cast<SomeSocketHandle>(
+                           satcom::lib::FileHandle(FDHandle())),
+                       std::bad_cast );
+
+    BOOST_CHECK_EQUAL( myh.dumpState(), 
+                       "handle: satcom::lib::SocketHandle<satcom::lib::SocketPolicy<satcom::lib::test::SomeAddressingPolicy, satcom::lib::test::SomeFramingPolicy, satcom::lib::test::SomeCommunicationPolicy, satcom::lib::test::SomeReadPolicy, satcom::lib::test::SomeWritePolicy, satcom::lib::test::SomeBufferingPolicy> >\n"
+                       "file.handle: -1\n"
+                       "file.refcount: 3\n"
+                       "socket.policy: satcom::lib::SocketPolicy<satcom::lib::test::SomeAddressingPolicy, satcom::lib::test::SomeFramingPolicy, satcom::lib::test::SomeCommunicationPolicy, satcom::lib::test::SomeReadPolicy, satcom::lib::test::SomeWritePolicy, satcom::lib::test::SomeBufferingPolicy>\n"
+                       "socket.protocol: satcom::lib::test::SomeProtocol\n"
+                       "socket.server: false\n" );
+
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketPolicy.ct b/Socket/SocketPolicy.ct
new file mode 100644 (file)
index 0000000..b2b2944
--- /dev/null
@@ -0,0 +1,54 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline template functions
+
+#include "SocketPolicy.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+#define SP_TemplateArgs(x1,x2,n,SomePolicy) BOOST_PP_COMMA_IF(n) class BOOST_PP_CAT(SomePolicy,_)
+#define SP_TemplateParams(x1,x2,n,SomePolicy) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(SomePolicy,_)
+
+template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SATLIB_SOCKET_POLICIES ) >
+prefix_ void satcom::lib::SocketPolicy< BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateParams, , SATLIB_SOCKET_POLICIES ) >::
+checkBaseOf(SocketPolicyBase const & other)
+{
+#   define SP_CheckPolicy(x1,x2,SomePolicy) dynamic_cast<SomePolicy const &>(other.BOOST_PP_CAT(the,SomePolicy)());
+    BOOST_PP_SEQ_FOR_EACH( SP_CheckPolicy, , SATLIB_SOCKET_POLICIES )
+#   undef SP_CheckPolicy
+}
+
+#undef SP_TemplateArgs
+#undef SP_TemplateParams
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketPolicy.hh b/Socket/SocketPolicy.hh
new file mode 100644 (file)
index 0000000..a2a0c05
--- /dev/null
@@ -0,0 +1,75 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_SocketPolicy_
+#define HH_SocketPolicy_ 1
+
+// Custom includes
+
+//#include "SocketPolicy.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    // This may be adapted to change the supported policies (however,
+    // ClientSocketHandle and ServerSocketHandle will probably have to
+    // be adjusted accordingly). However, AddressingPolicy MUST always
+    // be the first Policy member ...
+
+#   define SATLIB_SOCKET_POLICIES               \
+       (AddressingPolicy)                      \
+        (FramingPolicy)                         \
+       (CommunicationPolicy)                   \
+       (ReadPolicy)                            \
+       (WritePolicy)                           \
+       (BufferingPolicy)
+    
+    // The implementation file will for each Policy declared above
+    // define the following (SomePolicy is one of the above):
+    //
+    // struct SomePolicyBase;
+    // typedef UndefinedSomePolicy;
+    // template SomePolicyIs< SocketPolicy, Axis >
+    // template IfSomePolicyIs< SocketPolicy, Axis >
+    // template IfSomePolicyIsNot< SocketPolicy, Axis >
+    //
+    // Additionally the following are defined:
+    //
+    // class SocketPolicyBase
+    // template SocketPolicy< ..policies.. >
+    // template MakeSocketPolicy< ..args.. >
+    // template SocketPolicyIsBaseOf< Base, Derived >
+}}
+
+//////////////////////////////hh.e////////////////////////////////////////
+#include "SocketPolicy.ih"
+//#include "SocketPolicy.cci"
+#include "SocketPolicy.ct"
+//#include "SocketPolicy.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketPolicy.ih b/Socket/SocketPolicy.ih
new file mode 100644 (file)
index 0000000..58fcba3
--- /dev/null
@@ -0,0 +1,255 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef IH_SocketPolicy_
+#define IH_SocketPolicy_ 1
+
+// Custom includes
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/seq/pop_front.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
+
+#include <boost/type_traits.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/utility.hpp> // for enable_if
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+#   define SATLIB_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SATLIB_SOCKET_POLICIES )
+    
+    // This REALLY is bad ... but we just need an Address member in
+    // AddressingPolicyBase as long as ClientSocketHandle /
+    // ServerSocketHandle don't make use of enable_if for each and
+    // every member they define ...
+
+    struct AddressingPolicyBase
+    {
+        virtual ~ AddressingPolicyBase() {}
+        
+        class Address 
+        {
+        private:
+            Address();
+        };
+    };
+
+#   define SP_DeclareBase(x1,x2,SomePolicy)                                             \
+        struct BOOST_PP_CAT(SomePolicy,Base)                                            \
+        { virtual ~ BOOST_PP_CAT(SomePolicy,Base) () {} };                              \
+        typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy);
+
+    BOOST_PP_SEQ_FOR_EACH( SP_DeclareBase, , BOOST_PP_SEQ_POP_FRONT( SATLIB_SOCKET_POLICIES ) )
+
+#   undef SP_DeclareBase
+        
+    struct SocketPolicyBase
+    {
+        virtual ~SocketPolicyBase() {}
+
+#       define SP_DeclareTypedef(x1,x2,SomePolicy)                                              \
+            typedef BOOST_PP_CAT(SomePolicy,Base) SomePolicy;                                   \
+            BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_);         \
+            virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \
+                { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
+
+        BOOST_PP_SEQ_FOR_EACH( SP_DeclareTypedef, , SATLIB_SOCKET_POLICIES )
+
+#       undef SP_DeclareTypedef
+    };
+
+#   define SP_TemplateArgs(x1,x2,n,SomePolicy)                                  \
+        BOOST_PP_COMMA_IF( n )                                                  \
+        class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base)
+
+    template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SATLIB_SOCKET_POLICIES ) >
+    struct SocketPolicy
+        : public SocketPolicyBase
+    {
+#   define SP_DeclarePolicyMember(x1,x2,SomePolicy)                                     \
+        typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy;                                  \
+        SomePolicy BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_);                        \
+        BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const     \
+            { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
+
+        BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SATLIB_SOCKET_POLICIES )
+#   undef SP_DeclarePolicyMember
+
+        static void checkBaseOf(SocketPolicyBase const & other);
+    };
+
+#   undef SP_TemplateArgs
+
+namespace impl {
+
+    struct nil {};
+
+    template <int N>
+    struct SocketPolicy_rv
+    { int v[N+1]; };
+    
+    template <class Base, class Policy, int N>
+    struct MakeSocketPolicy_merge
+    {};
+
+#   define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy)            \
+        BOOST_PP_COMMA_IF( m )                                                  \
+        BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy )
+
+#    define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SATLIB_SOCKET_POLICIES_N ) )
+#    define BOOST_PP_LOCAL_MACRO(n)                                                                                             \
+        SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SATLIB_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, SATLIB_SOCKET_POLICIES )                    \
+               > type;                                                                                                          \
+        };
+
+#   include BOOST_PP_LOCAL_ITERATE()
+
+#   undef SP_DeclareMakeSocketPolicy_merge_member
+
+    struct MakeSocketPolicy_fold
+    {
+        template <class Base, class Policy>
+        struct apply
+            : MakeSocketPolicy_merge<Base,
+                                     Policy,
+                                     sizeof(MakeSocketPolicy_merge_(static_cast<Policy*>(0)))>
+        {};
+
+        template <class Base>
+        struct apply<Base,nil>
+        {
+            typedef Base type;
+        };
+    };
+
+    template <class Base, class Vector>
+    struct MakeSocketPolicy_impl
+    {
+        typedef typename boost::mpl::fold< Vector, Base, MakeSocketPolicy_fold >::type policy;
+    };
+
+#   define SP_DeclareArguments(x1,x2,n,SomePolicy)      \
+       BOOST_PP_COMMA_IF( n )                          \
+       typename Base::SomePolicy *
+
+    template <class Base>
+    SocketPolicy_rv<1> SocketPolicy_checkcompat_(
+        BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SATLIB_SOCKET_POLICIES ) );
+
+#   undef SP_DeclareArguments
+
+    template <class Base>
+    SocketPolicy_rv<2> SocketPolicy_checkcompat_( 
+        BOOST_PP_ENUM_PARAMS( SATLIB_SOCKET_POLICIES_N, void * BOOST_PP_INTERCEPT ) );
+
+    template <int Size>
+    struct SocketPolicy_checkcompat
+        : public boost::false_type
+    {};
+
+    template<>
+    struct SocketPolicy_checkcompat<sizeof(SocketPolicy_rv<1>)>
+        : public boost::true_type
+    {};
+
+
+#   define SP_DeclareArguments(x1,x2,n,SomePolicy)      \
+        BOOST_PP_COMMA_IF( n )                          \
+        static_cast<typename Derived::SomePolicy *>(0)
+
+    template <class Base, class Derived>
+    struct SocketPolicy_compatibility
+        : public SocketPolicy_checkcompat< sizeof(
+            SocketPolicy_checkcompat_<Base>(
+                BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SATLIB_SOCKET_POLICIES ) )) >
+    {};
+
+} // namespace impl
+
+    template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SATLIB_SOCKET_POLICIES_N, class T, satcom::lib::impl::nil ) >
+    class MakeSocketPolicy
+        : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >,
+                                  impl::MakeSocketPolicy_impl< T0, boost::mpl::vector< BOOST_PP_ENUM_SHIFTED_PARAMS( SATLIB_SOCKET_POLICIES_N, T ) > >,
+                                  impl::MakeSocketPolicy_impl< SocketPolicy<>,
+                                                               boost::mpl::vector< BOOST_PP_ENUM_PARAMS( SATLIB_SOCKET_POLICIES_N, T ) > > >::type
+    {};
+
+    template <class BasePolicy, class DerivedPolicy>
+    struct SocketPolicyIsBaseOf
+        : public boost::mpl::if_< boost::mpl::and_< boost::is_convertible< BasePolicy*, SocketPolicyBase* >,
+                                                    boost::is_convertible< DerivedPolicy*, SocketPolicyBase* > >,
+                                  impl::SocketPolicy_compatibility<BasePolicy,DerivedPolicy>,
+                                  boost::false_type >::type
+    {};
+
+#   define SP_DefineConditions(x1,x2,SomePolicy)                                                \
+        template <class Policy, class Trait>                                                    \
+        struct BOOST_PP_CAT(SomePolicy,Is)                                                      \
+            : public boost::is_convertible< typename Policy::SomePolicy*, Trait* >              \
+        {};                                                                                     \
+                                                                                                \
+        template <class Policy, class Trait>                                                    \
+        struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),Is)                                     \
+            : public boost::enable_if< BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait> >              \
+        {};                                                                                     \
+                                                                                                \
+        template <class Policy, class Trait>                                                    \
+        struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),IsNot)                                  \
+            : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value >   \
+        {};
+
+    BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SATLIB_SOCKET_POLICIES )
+
+#   undef SP_DefineConditions
+
+}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketPolicy.test.cc b/Socket/SocketPolicy.test.cc
new file mode 100644 (file)
index 0000000..af167a4
--- /dev/null
@@ -0,0 +1,140 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "SocketPolicy.test.hh"
+//#include "SocketPolicy.test.ih"
+
+// Custom includes
+#include "SocketPolicy.hh"
+#include "SocketPolicy.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/utility.hpp> // enable_if
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace satcom::lib;
+
+namespace {
+    struct INetAddressingPolicy : public AddressingPolicyBase {};
+    struct UnixAddressingPolicy : public AddressingPolicyBase {};
+
+    struct StreamFramingPolicy : public FramingPolicyBase {};
+    struct DgramFramingPolicy : public FramingPolicyBase {};
+
+    struct ConnectedCommunicationPolicy : public CommunicationPolicyBase {};
+    struct UnconnectedCommunicationPolicy : public CommunicationPolicyBase {};
+
+    struct ReadablePolicy : public ReadPolicyBase {};
+    struct UnreadablePolicy : public ReadPolicyBase {};
+
+    struct WritablePolicy : public WritePolicyBase {};
+    struct UnwritablePolicy : public WritePolicyBase {};
+    
+    struct SocketBufferingPolicy : public BufferingPolicyBase {};
+
+    template <class Policy>
+    struct ConvertibleValue
+    {
+        ConvertibleValue() {}
+        ConvertibleValue(ConvertibleValue const & other) {}
+
+        template <class OtherPolicy>
+        ConvertibleValue(ConvertibleValue<OtherPolicy> const & other, 
+                         typename boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy> >::type * = 0)
+            {}
+
+        ConvertibleValue const & operator=(ConvertibleValue const & other)
+            { return *this; }
+
+        template <class OtherPolicy>
+        typename boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy>, 
+                                   ConvertibleValue >::type const & 
+        operator=(ConvertibleValue<OtherPolicy> const & other)
+            { return *this; }
+    };
+
+}
+
+BOOST_AUTO_UNIT_TEST(socketPolicy)
+{
+    // All these checks are really compile-time checks ...
+
+    typedef MakeSocketPolicy<
+        UnixAddressingPolicy,
+        ConnectedCommunicationPolicy,
+        ReadablePolicy>::policy Policy1;
+
+    typedef SocketPolicy<
+        UnixAddressingPolicy,
+        UnspecifiedFramingPolicy,
+        ConnectedCommunicationPolicy,
+        ReadablePolicy,
+        UnspecifiedWritePolicy,
+        UnspecifiedBufferingPolicy> Policy2;
+        
+    BOOST_MPL_ASSERT(( boost::is_same<Policy1,Policy2> ));
+
+    typedef MakeSocketPolicy<
+        Policy1,
+        UnspecifiedCommunicationPolicy>::policy Policy3;
+
+    typedef SocketPolicy<
+        UnixAddressingPolicy,
+        UnspecifiedFramingPolicy,
+        UnspecifiedCommunicationPolicy,
+        ReadablePolicy,
+        UnspecifiedWritePolicy,
+        UnspecifiedBufferingPolicy> Policy4;
+
+    BOOST_MPL_ASSERT(( boost::is_same<Policy3,Policy4> ));
+    BOOST_MPL_ASSERT_NOT(( boost::is_same<Policy1, Policy3> ));
+
+    BOOST_MPL_ASSERT(( SocketPolicyIsBaseOf<Policy3,Policy1> ));
+    BOOST_MPL_ASSERT_NOT(( SocketPolicyIsBaseOf<Policy1,Policy3> ));
+    BOOST_MPL_ASSERT_NOT(( SocketPolicyIsBaseOf<Policy1,int> ));
+
+    // The following should fail at compile time
+    // BOOST_MPL_ASSERT(( SocketPolicyIsBaseOf<Policy1,Policy3> ));
+   
+    ConvertibleValue<Policy1> p1;
+    ConvertibleValue<Policy3> p3(p1);
+
+    p3 = p1;
+    // The following should fail at compile time
+    // p1 = p3;
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketPolicy.test.hh b/Socket/SocketPolicy.test.hh
new file mode 100644 (file)
index 0000000..cebba2d
--- /dev/null
@@ -0,0 +1,130 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_SocketPolicy_test_
+#define HH_SocketPolicy_test_ 1
+
+// Custom includes
+#include "SocketPolicy.hh"
+#include "FileHandle.hh"
+
+//#include "SocketPolicy.test.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+namespace test {
+
+    struct SomeAddressingPolicy : public satcom::lib::AddressingPolicyBase
+    {
+        typedef unsigned Address;
+        
+        static void peer(FileHandle handle, unsigned & addr)
+            { addr=1; }
+        static void local(FileHandle, unsigned & addr)
+            { addr=2; }
+        static void connect(FileHandle, unsigned addr)
+            {}
+        static void bind(FileHandle, unsigned addr)
+            {}
+    };
+
+    struct SomeFramingPolicy : public satcom::lib::FramingPolicyBase
+    {};
+
+    struct SomeCommunicationPolicy : public satcom::lib::CommunicationPolicyBase
+    {
+        static int accept(FileHandle handle, unsigned & addr)
+            { addr = 3; return -1; }
+    };
+
+    struct SomeReadPolicy : public satcom::lib::ReadPolicyBase
+    {
+        static unsigned const TEST_SIZE = 9;
+
+        static unsigned read(FileHandle handle, char * buffer, unsigned size)
+            {
+                int const n (size<TEST_SIZE?size:TEST_SIZE);
+                ::memcpy(buffer,"TEST-READ",n);
+                return n;
+            }
+
+        static unsigned readfrom(FileHandle handle, char * buffer, unsigned size,
+                                 unsigned & address)
+            {
+                return read(handle,buffer,size);
+            }
+    };
+
+    struct SomeWritePolicy : public satcom::lib::WritePolicyBase
+    {
+        static unsigned write(FileHandle handle, char const * buffer, unsigned size)
+            {
+                if (size == 10 && ::strncmp(buffer,"TEST-WRITE",10) == 0)
+                    return size;
+                else
+                    return 0;
+            }
+
+        static unsigned writeto(FileHandle handle, unsigned address,
+                                char const * buffer, unsigned size)
+            {
+                return write(handle,buffer,size);
+            }
+    };
+    
+    struct SomeBufferingPolicy : public satcom::lib::BufferingPolicyBase
+    {
+        static unsigned rcvbuf(FileHandle handle)
+            { return 0; }
+        static unsigned rcvbuf(FileHandle handle, unsigned size)
+            { return 0; }
+
+        static unsigned sndbuf(FileHandle handle)
+            { return 0; }
+        static unsigned sndbuf(FileHandle handle, unsigned size)
+            { return 0; }
+    };
+
+    typedef satcom::lib::MakeSocketPolicy<
+        SomeAddressingPolicy,
+        SomeFramingPolicy,
+        SomeCommunicationPolicy,
+        SomeReadPolicy,
+        SomeWritePolicy,
+        SomeBufferingPolicy
+        >::policy SomeSocketPolicy;
+
+}}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "SocketPolicy.test.cci"
+//#include "SocketPolicy.test.ct"
+//#include "SocketPolicy.test.cti"
+//#include "SocketPolicy.test.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketProtocol.cc b/Socket/SocketProtocol.cc
new file mode 100644 (file)
index 0000000..f82cd5f
--- /dev/null
@@ -0,0 +1,46 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "SocketProtocol.hh"
+//#include "SocketProtocol.ih"
+
+// Custom includes
+
+//#include "SocketProtocol.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void satcom::lib::SocketProtocol::state(SocketStateMap & map, unsigned lod)
+    const
+{}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "SocketProtocol.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketProtocol.cci b/Socket/SocketProtocol.cci
new file mode 100644 (file)
index 0000000..a10def6
--- /dev/null
@@ -0,0 +1,54 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+//#include "SocketProtocol.ih"
+
+// Custom includes
+#include <boost/assert.hpp>
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ satcom::lib::SocketProtocol::SocketProtocol()
+    : body_(0)
+{}
+
+prefix_  satcom::lib::SocketProtocol::~SocketProtocol()
+{}
+
+prefix_ satcom::lib::SocketBody & satcom::lib::SocketProtocol::body()
+    const
+{
+    BOOST_ASSERT( body_ );
+    return *body_;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketProtocol.cti b/Socket/SocketProtocol.cti
new file mode 100644 (file)
index 0000000..f2b3287
--- /dev/null
@@ -0,0 +1,51 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline template functions
+
+//#include "SocketProtocol.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class SocketPolicy>
+prefix_ satcom::lib::ConcreteSocketProtocol<SocketPolicy>::~ConcreteSocketProtocol()
+{}
+
+template <class SocketPolicy>
+prefix_ typename satcom::lib::ConcreteSocketProtocol<SocketPolicy>::Policy const &
+satcom::lib::ConcreteSocketProtocol<SocketPolicy>::policy()
+    const
+{
+    return policy_;
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh
new file mode 100644 (file)
index 0000000..4dbd95b
--- /dev/null
@@ -0,0 +1,122 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_SocketProtocol_
+#define HH_SocketProtocol_ 1
+
+// Custom includes
+#include <boost/utility.hpp>
+// TODO: this is really bad. This includes and predefs should be restructured
+#include "SocketHandle.ih"
+
+//#include "SocketProtocol.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    class SocketPolicyBase;
+
+    class SocketProtocol : boost::noncopyable
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        SocketProtocol();
+        virtual ~SocketProtocol() = 0;
+
+        // default default constructor
+        // no copy
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        SocketBody & body() const;
+        virtual SocketPolicyBase const & policy() const = 0;
+        
+        ///////////////////////////////////////////////////////////////////////////
+        // Virtual interface
+
+        virtual std::auto_ptr<SocketProtocol> clone() const = 0;
+        virtual unsigned available() const = 0;
+        virtual bool eof() const = 0;
+        virtual void state(SocketStateMap & map, unsigned lod) const;
+
+    protected:
+
+    private:
+        // backpointer to owning SocketBody instance
+        SocketBody * body_;
+        friend class SocketBody; 
+   };
+
+    template <class SocketPolicy>
+    class ConcreteSocketProtocol
+        : public virtual SocketProtocol
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef SocketPolicy Policy;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        ~ConcreteSocketProtocol() = 0;
+
+        // no default constructor
+        // no copy
+        // no conversion constructors
+
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+
+        Policy const & policy() const;
+
+    protected:
+
+    private:
+        Policy policy_;
+
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "SocketProtocol.cci"
+//#include "SocketProtocol.ct"
+#include "SocketProtocol.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketProtocol.test.cc b/Socket/SocketProtocol.test.cc
new file mode 100644 (file)
index 0000000..fdd880c
--- /dev/null
@@ -0,0 +1,56 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "SocketProtocol.test.hh"
+//#include "SocketProtocol.test.ih"
+
+// Custom includes
+#include "SocketProtocol.hh"
+#include "SocketPolicy.hh"
+#include "SocketProtocol.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(socketProtocol)
+{
+    satcom::lib::test::SomeProtocol protocol;
+
+    // This would fail an assertion ...
+    // BOOST_CHECK( protocol.body() == 0 ); 
+
+    protocol.policy();
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/SocketProtocol.test.hh b/Socket/SocketProtocol.test.hh
new file mode 100644 (file)
index 0000000..047a6a9
--- /dev/null
@@ -0,0 +1,68 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_SocketProtocol_test_
+#define HH_SocketProtocol_test_ 1
+
+// Custom includes
+#include "SocketProtocol.hh"
+#include "SocketPolicy.test.hh"
+#include "ProtocolClientSocketHandle.hh"
+
+//#include "SocketProtocol.test.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+namespace test {
+
+    class SomeProtocol
+        : public ConcreteSocketProtocol<SomeSocketPolicy>
+    {
+    public:
+        ~SomeProtocol() {}
+        
+        void init_client() const {}
+        void init_server() const {}
+
+        std::auto_ptr<SocketProtocol> clone() const 
+            { return std::auto_ptr<SocketProtocol>(new SomeProtocol()); }
+        unsigned available() const 
+            { return Policy::ReadPolicy::TEST_SIZE; }
+        bool eof() const 
+            { return false; }
+    };
+
+}}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "SocketProtocol.test.cci"
+//#include "SocketProtocol.test.ct"
+//#include "SocketProtocol.test.cti"
+//#include "SocketProtocol.test.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/TCPProtocol.cc b/Socket/TCPProtocol.cc
new file mode 100644 (file)
index 0000000..f444ac3
--- /dev/null
@@ -0,0 +1,97 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "TCPProtocol.hh"
+//#include "TCPProtocol.ih"
+
+// Custom includes
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/ioctl.h>
+#include <linux/sockios.h> // for SIOCINQ / SIOCOUTQ
+#include "SocketHandle.hh"
+
+//#include "TCPProtocol.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ bool satcom::lib::TCPProtocol::nodelay()
+    const
+{
+    int value;
+    socklen_t len (sizeof(value));
+    if (::getsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&value,&len) < 0)
+        throw SystemException(errno);
+    return value;
+}
+
+prefix_ void satcom::lib::TCPProtocol::nodelay(bool value)
+    const
+{
+    int ivalue (value);
+    if (::setsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&ivalue,sizeof(ivalue)) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ unsigned satcom::lib::TCPProtocol::siocinq()
+    const
+{
+    int n;
+    if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
+        throw SystemException(errno);
+    return n;
+}
+
+prefix_ unsigned satcom::lib::TCPProtocol::siocoutq()
+    const
+{
+    int n;
+    if (::ioctl(body().fd(),SIOCOUTQ,&n) < 0)
+        throw SystemException(errno);
+    return n;
+}
+
+prefix_ unsigned satcom::lib::TCPProtocol::available()
+    const
+{
+    return siocinq();
+}
+
+prefix_ bool satcom::lib::TCPProtocol::eof()
+    const
+{
+    return body().readable() && available()==0;
+}
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "TCPProtocol.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/TCPProtocol.hh b/Socket/TCPProtocol.hh
new file mode 100644 (file)
index 0000000..adf029f
--- /dev/null
@@ -0,0 +1,60 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_TCPProtocol_
+#define HH_TCPProtocol_ 1
+
+// Custom includes
+#include "SocketProtocol.hh"
+
+//#include "TCPProtocol.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    class TCPProtocol
+        : public virtual SocketProtocol
+    {
+    public:
+        bool nodelay() const;
+        void nodelay(bool value) const;
+
+        unsigned siocinq() const;
+        unsigned siocoutq() const;
+        unsigned available() const;
+        bool eof() const;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "TCPProtocol.cci"
+//#include "TCPProtocol.ct"
+//#include "TCPProtocol.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/TCPSocketHandle.cc b/Socket/TCPSocketHandle.cc
new file mode 100644 (file)
index 0000000..0eb1446
--- /dev/null
@@ -0,0 +1,90 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "TCPSocketHandle.hh"
+//#include "TCPSocketHandle.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include "Utils/Exception.hh"
+
+//#include "TCPSocketHandle.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void satcom::lib::TCPv4SocketProtocol::init_client()
+    const
+{
+    int sock = ::socket(PF_INET,SOCK_STREAM,0);
+    if (sock < 0)
+        throw SystemException(errno);
+    body().fd(sock);
+}
+
+prefix_ void
+satcom::lib::TCPv4SocketProtocol::init_client(INet4Address const & address)
+    const
+{
+    init_client();
+    connect(address);
+}
+
+prefix_ void satcom::lib::TCPv4SocketProtocol::init_server()
+    const
+{
+    int sock = ::socket(PF_INET,SOCK_STREAM,0);
+    if (sock < 0)
+        throw SystemException(errno);
+    body().fd(sock);
+}
+
+prefix_ void satcom::lib::TCPv4SocketProtocol::init_server(INet4Address const & address,
+                                                           unsigned backlog)
+    const
+{
+    init_server();
+    bind(address);
+    reuseaddr(true);
+    if (::listen(body().fd(),backlog) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::TCPv4SocketProtocol::clone()
+    const
+{
+    return std::auto_ptr<SocketProtocol>(new TCPv4SocketProtocol());
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "TCPSocketHandle.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/TCPSocketHandle.hh b/Socket/TCPSocketHandle.hh
new file mode 100644 (file)
index 0000000..5d3b2c0
--- /dev/null
@@ -0,0 +1,107 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// TODO: Implement possibly non-blocking connect and SO_ERROR in the
+// protocol interface
+
+#ifndef HH_TCPSocketHandle_
+#define HH_TCPSocketHandle_ 1
+
+// Custom includes
+#include "INetProtocol.hh"
+#include "TCPProtocol.hh"
+#include "BSDSocketProtocol.hh"
+#include "FramingPolicy.hh"
+#include "CommunicationPolicy.hh"
+#include "ReadWritePolicy.hh"
+#include "BufferingPolicy.hh"
+#include "ProtocolClientSocketHandle.hh"
+#include "ProtocolServerSocketHandle.hh"
+
+//#include "TCPSocketHandle.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    typedef MakeSocketPolicy<
+        INet4AddressingPolicy,
+        StreamFramingPolicy,
+        ConnectedCommunicationPolicy,
+        ReadablePolicy,
+        WriteablePolicy,
+        SocketBufferingPolicy
+        >::policy TCPv4Socket_Policy;
+
+    class TCPv4SocketProtocol
+        : public ConcreteSocketProtocol<TCPv4Socket_Policy>,
+          public IPv4Protocol, 
+          public TCPProtocol,
+          public BSDSocketProtocol,
+          public AddressableBSDSocketProtocol
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // internal interface
+
+        void init_client() const;
+        void init_client(INet4Address const & address) const;
+        void init_server() const;
+        void init_server(INet4Address const & address, unsigned backlog=1) const;
+
+        std::auto_ptr<SocketProtocol> clone() const;
+    };
+
+    typedef ProtocolClientSocketHandle<TCPv4SocketProtocol> TCPv4ClientSocketHandle;
+    typedef ProtocolServerSocketHandle<TCPv4SocketProtocol> TCPv4ServerSocketHandle;
+
+    typedef MakeSocketPolicy<
+        TCPv4Socket_Policy,
+        INet6AddressingPolicy
+        >::policy TCPv6Socket_Policy;
+
+    class TCPv6SocketProtocol
+        : public ConcreteSocketProtocol<TCPv6Socket_Policy>, 
+          public IPv6Protocol,
+          public TCPProtocol,
+          public BSDSocketProtocol,
+          public AddressableBSDSocketProtocol
+    {
+        // TODO: Implement
+    };
+
+    typedef ProtocolClientSocketHandle<TCPv6SocketProtocol> TCPv6ClientSocketHandle;
+    typedef ProtocolServerSocketHandle<TCPv6SocketProtocol> TCPv6ServerSocketHandle;
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "TCPSocketHandle.cci"
+//#include "TCPSocketHandle.ct"
+//#include "TCPSocketHandle.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/TCPSocketHandle.test.cc b/Socket/TCPSocketHandle.test.cc
new file mode 100644 (file)
index 0000000..2a8659b
--- /dev/null
@@ -0,0 +1,239 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "TCPSocketHandle.test.hh"
+//#include "TCPSocketHandle.test.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "TCPSocketHandle.hh"
+#include <iostream>
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+
+    void error(char const * fn, char const * proc="")
+    {
+        std::cerr << "\n" << proc << fn << ": " << strerror(errno) << std::endl;
+    }
+
+    void fail(char const * fn)
+    {
+        error(fn,"server: ");
+        _exit(1);
+    }
+
+    int server_pid = 0;
+
+    void start(void (*fn)())
+    {
+        server_pid = ::fork();
+        if (server_pid < 0) BOOST_FAIL("fork()");
+        if (server_pid == 0) {
+            (*fn)();
+            _exit(0);
+        }
+    }
+
+    void wait()
+    {
+        int status;
+        if (waitpid(server_pid,&status,0)<0)
+            BOOST_FAIL("waitpid()");
+        BOOST_CHECK_EQUAL( status , 0 );
+    }
+
+    void stop()
+    {
+        kill(server_pid,9);
+        wait();
+    }
+
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+    void server()
+    {
+        int serv = socket(PF_INET,SOCK_STREAM,0);
+        if (serv<0) fail("socket()");
+        int v = 1;
+        if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
+            fail("setsockopt()");
+        struct sockaddr_in sin;
+        sin.sin_family = AF_INET;
+        sin.sin_port = htons(12345);
+        sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+        if (bind(serv,(struct sockaddr *)&sin,sizeof(sin))<0) fail("bind()");
+        if (listen(serv,1)<0) fail("listen()");
+        int sock = accept(serv,0,0);
+        if (sock < 0) fail("accept()");
+
+        char buffer[1024];
+        while (1) {
+            int n = read(sock,buffer,1024);
+            if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
+                break;
+            write(sock,buffer,n);
+        }
+
+        if (shutdown(sock, SHUT_RDWR) < 0) fail("shutdown()");
+        if (close(sock) < 0) fail("close()");
+        if (close(serv) < 0) fail("close()");
+    }
+
+}
+
+BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle)
+{
+    {
+        satcom::lib::TCPv4ClientSocketHandle sock;
+
+        BOOST_CHECK_THROW( sock.connect(satcom::lib::INet4Address("127.0.0.1:12345")), satcom::lib::SystemException );
+        BOOST_CHECK_THROW( sock.protocol().connect("127.0.0.1:12345"), satcom::lib::SystemException );
+    }
+
+    {
+        start(server);
+        satcom::lib::TCPv4ClientSocketHandle sock;
+        BOOST_CHECK_NO_THROW( sock.bind("127.0.0.1:23456") );
+        BOOST_CHECK_NO_THROW( sock.connect("127.0.0.1:12345") );
+        BOOST_CHECK( sock.peer() == "127.0.0.1:12345" );
+        BOOST_CHECK( sock.local() == "127.0.0.1:23456" );
+        BOOST_CHECK( sock.blocking() );
+        BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
+        BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
+        BOOST_CHECK_NO_THROW( sock.sndbuf(2048) );
+        BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
+        BOOST_CHECK_NO_THROW( sock.write("TEST-WRITE") );
+        BOOST_CHECK_EQUAL( sock.read(), "TEST-WRITE" );
+        // this fails with ENOFILE ... why ????
+        // BOOST_CHECK_NO_THROW( sock.protocol().timestamp() );
+        BOOST_CHECK( !sock.eof() );
+        sock.write("QUIT");
+        sleep(1);
+        stop();
+        sleep(1);
+        BOOST_CHECK_EQUAL( sock.read(), "" );
+        BOOST_CHECK( sock.eof() );
+        BOOST_CHECK( !sock );
+    }
+    
+    {
+        satcom::lib::TCPv4ClientSocketHandle sock;
+
+        // Since this is a TCP socket, most of the calls will fail or
+        // are at least not sensible ...
+        // I'll have to move those to a UDPSocket test ... they should
+        // realy only be in the UDP Protocol implementation
+        BOOST_CHECK_NO_THROW( sock.protocol().mcTTL() );
+        BOOST_CHECK_THROW( sock.protocol().mcTTL(1), satcom::lib::SystemException );
+        BOOST_CHECK_NO_THROW( sock.protocol().mcLoop() );
+        BOOST_CHECK_NO_THROW( sock.protocol().mcLoop(false) );
+        BOOST_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0") );
+        BOOST_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0","127.0.0.1:0") );
+        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"), satcom::lib::SystemException );
+        
+        // The following setsockopts are hard to REALLY test ...
+        BOOST_CHECK_NO_THROW( sock.protocol().nodelay(true) );
+        BOOST_CHECK( sock.protocol().nodelay() );
+        BOOST_CHECK_EQUAL( sock.protocol().siocinq(), 0u );
+        BOOST_CHECK_EQUAL( sock.protocol().siocoutq(), 0u );
+
+        BOOST_CHECK_NO_THROW( sock.protocol().reuseaddr(true) );
+        BOOST_CHECK( sock.protocol().reuseaddr() );
+        BOOST_CHECK_NO_THROW( sock.protocol().linger(true,0) );
+        BOOST_CHECK( sock.protocol().linger() == std::make_pair(true, 0u) );
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+    void client()
+    {
+        int sock = socket(PF_INET,SOCK_STREAM,0);
+        if (sock<0) fail("socket()");
+        struct sockaddr_in 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("connect()");
+        
+        char buffer[1024];
+        while (1) {
+            int n = read(sock,buffer,1024);
+            if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
+                break;
+            write(sock,buffer,n);
+        }
+
+        if (shutdown(sock, SHUT_RDWR) < 0) fail("shutdown()");
+        if (close(sock) < 0) fail("close()");
+    }
+
+}
+
+BOOST_AUTO_UNIT_TEST(tcpv4ServerSocketHandle)
+{
+    {
+        BOOST_CHECKPOINT("Opening server socket");
+        satcom::lib::TCPv4ServerSocketHandle server ("127.0.0.1:12346");
+        BOOST_CHECKPOINT("Starting client");
+        start(client);
+
+        BOOST_CHECKPOINT("Accepting connection");
+        satcom::lib::TCPv4ClientSocketHandle client = server.accept();
+        BOOST_CHECK_NO_THROW(client.write("QUIT"));
+
+        BOOST_CHECKPOINT("Stopping client");
+        sleep(1);
+        stop();
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Socket/main.test.cc b/Socket/main.test.cc
new file mode 100644 (file)
index 0000000..fd4c97a
--- /dev/null
@@ -0,0 +1,43 @@
+// $Id: main.test.cc 32 2006-03-23 16:24:56Z sbund $
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+//#include "test.hh"
+//#include "test.ih"
+
+// Custom includes
+#define BOOST_AUTO_TEST_MAIN
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// End:
diff --git a/Utils/Exception.cc b/Utils/Exception.cc
new file mode 100644 (file)
index 0000000..a534910
--- /dev/null
@@ -0,0 +1,47 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "Exception.hh"
+//#include "Exception.ih"
+
+// Custom includes
+#include <cstring>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ char const * satcom::lib::SystemException::what()
+    const throw()
+{
+    return std::strerror(this->err);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Utils/Exception.hh b/Utils/Exception.hh
new file mode 100644 (file)
index 0000000..6c3e8b1
--- /dev/null
@@ -0,0 +1,54 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_Exception_
+#define HH_Exception_ 1
+
+// Custom includes
+#include <exception>
+
+//#include "Exception.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    struct SystemException : public std::exception
+    {
+        SystemException(int err_) : err(err_) {};
+        virtual char const * what() const throw();
+        int err;
+    };
+    
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Exception.cci"
+//#include "Exception.ct"
+//#include "Exception.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Utils/SConscript b/Utils/SConscript
new file mode 100644 (file)
index 0000000..81cb37c
--- /dev/null
@@ -0,0 +1,7 @@
+Import('env')
+import SatSCons
+
+###########################################################################
+
+SatSCons.StandardTargets(env)
+SatSCons.Lib(env, 'Utils',  SatSCons.GlobSources())
diff --git a/Utils/TypeInfo.cc b/Utils/TypeInfo.cc
new file mode 100644 (file)
index 0000000..c6860f5
--- /dev/null
@@ -0,0 +1,62 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+#include "TypeInfo.hh"
+//#include "TypeInfo.ih"
+
+// Custom includes
+#include "malloc.h"
+#define HAVE_DECL_BASENAME 1
+#define HAVE_DECL_ASPRINTF 1
+#define HAVE_DECL_VASPRINTF 1
+#include "impl/demangle.h"
+
+//#include "TypeInfo.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+
+// 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 satcom::lib::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) 
+        ::free(demangled);
+    return name;
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "TypeInfo.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Utils/TypeInfo.hh b/Utils/TypeInfo.hh
new file mode 100644 (file)
index 0000000..72168b6
--- /dev/null
@@ -0,0 +1,51 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_TypeInfo_
+#define HH_TypeInfo_ 1
+
+// Custom includes
+#include <string>
+#include <typeinfo>
+
+//#include "TypeInfo.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    std::string prettyName(std::type_info const & type);
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "TypeInfo.cci"
+//#include "TypeInfo.ct"
+//#include "TypeInfo.cti"
+//#include "TypeInfo.mpp"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Utils/TypeInfo.test.cc b/Utils/TypeInfo.test.cc
new file mode 100644 (file)
index 0000000..74218af
--- /dev/null
@@ -0,0 +1,67 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "TypeInfo.test.hh"
+//#include "TypeInfo.test.ih"
+
+// Custom includes
+#include "TypeInfo.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace test {
+    
+    struct Base {
+        virtual ~Base() {}
+    };
+
+    template <class C, unsigned N>
+    struct Foo : public Base
+    {};
+
+    enum Blub { A, B, C };
+}
+
+BOOST_AUTO_UNIT_TEST(prettyName)
+{
+    typedef test::Foo< test::Foo<test::Blub, 1>, 10> TestType;
+    TestType ob;
+    test::Base const & baseOb(ob);
+
+    BOOST_CHECK_EQUAL( satcom::lib::prettyName(typeid(int)), "int");
+    BOOST_CHECK_EQUAL( satcom::lib::prettyName(typeid(baseOb)), "test::Foo<test::Foo<test::Blub, 1>, 10>" );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Utils/impl/demangle.h b/Utils/impl/demangle.h
new file mode 100644 (file)
index 0000000..b3b8c58
--- /dev/null
@@ -0,0 +1,533 @@
+/* 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)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+
+#if !defined (DEMANGLE_H)
+#define DEMANGLE_H
+
+#include "libiberty.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* 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;
+                                            same as ARM except for
+                                            template arguments, etc. */
+#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)
+
+/* Enumeration of possible demangling styles.
+
+   Lucid and ARM styles are still kept logically distinct, even though
+   they now both behave identically.  The resulting style is actual the
+   union of both.  I.E. either style recognizes both "__pt__" and "__rf__"
+   for operator "->", even though the first is lucid style and the second
+   is ARM style. (FIXME?) */
+
+extern enum demangling_styles
+{
+  no_demangling = -1,
+  unknown_demangling = 0,
+  auto_demangling = DMGL_AUTO,
+  gnu_demangling = DMGL_GNU,
+  lucid_demangling = DMGL_LUCID,
+  arm_demangling = DMGL_ARM,
+  hp_demangling = DMGL_HP,
+  edg_demangling = DMGL_EDG,
+  gnu_v3_demangling = DMGL_GNU_V3,
+  java_demangling = DMGL_JAVA,
+  gnat_demangling = DMGL_GNAT
+} current_demangling_style;
+
+/* 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 GNU_V3_DEMANGLING_STYLE_STRING        "gnu-v3"
+#define JAVA_DEMANGLING_STYLE_STRING          "java"
+#define GNAT_DEMANGLING_STYLE_STRING          "gnat"
+
+/* Some macros to test what demangling style is active. */
+
+#define CURRENT_DEMANGLING_STYLE current_demangling_style
+#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
+#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
+#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
+#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM)
+#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP)
+#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG)
+#define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3)
+#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
+#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
+
+/* Provide information about the available demangle styles. This code is
+   pulled from gdb into libiberty because it is useful to binutils also.  */
+
+extern const struct demangler_engine
+{
+  const char *const demangling_style_name;
+  const enum demangling_styles demangling_style;
+  const char *const demangling_style_doc;
+} libiberty_demanglers[];
+
+extern char *
+cplus_demangle PARAMS ((const char *mangled, int options));
+
+extern int
+cplus_demangle_opname PARAMS ((const char *opname, char *result, int options));
+
+extern const char *
+cplus_mangle_opname PARAMS ((const char *opname, int options));
+
+/* Note: This sets global state.  FIXME if you care about multi-threading. */
+
+extern void
+set_cplus_marker_for_demangling PARAMS ((int ch));
+
+extern enum demangling_styles 
+cplus_demangle_set_style PARAMS ((enum demangling_styles style));
+
+extern enum demangling_styles 
+cplus_demangle_name_to_style PARAMS ((const char *name));
+
+/* V3 ABI demangling entry points, defined in cp-demangle.c.  */
+extern char*
+cplus_demangle_v3 PARAMS ((const char* mangled, int options));
+
+extern char*
+java_demangle_v3 PARAMS ((const char* mangled));
+
+
+enum gnu_v3_ctor_kinds {
+  gnu_v3_complete_object_ctor = 1,
+  gnu_v3_base_object_ctor,
+  gnu_v3_complete_object_allocating_ctor
+};
+
+/* Return non-zero iff NAME is the mangled form of a constructor name
+   in the G++ V3 ABI demangling style.  Specifically, return an `enum
+   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));
+
+
+enum gnu_v3_dtor_kinds {
+  gnu_v3_deleting_dtor = 1,
+  gnu_v3_complete_object_dtor,
+  gnu_v3_base_object_dtor
+};
+
+/* Return non-zero iff NAME is the mangled form of a destructor name
+   in the G++ V3 ABI demangling style.  Specifically, return an `enum
+   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));
+
+/* The V3 demangler works in two passes.  The first pass builds a tree
+   representation of the mangled name, and the second pass turns the
+   tree representation into a demangled string.  Here we define an
+   interface to permit a caller to build their own tree
+   representation, which they can pass to the demangler to get a
+   demangled string.  This can be used to canonicalize user input into
+   something which the demangler might output.  It could also be used
+   by other demanglers in the future.  */
+
+/* These are the component types which may be found in the tree.  Many
+   component types have one or two subtrees, referred to as left and
+   right (a component type with only one subtree puts it in the left
+   subtree).  */
+
+enum demangle_component_type
+{
+  /* A name, with a length and a pointer to a string.  */
+  DEMANGLE_COMPONENT_NAME,
+  /* A qualified name.  The left subtree is a class or namespace or
+     some such thing, and the right subtree is a name qualified by
+     that class.  */
+  DEMANGLE_COMPONENT_QUAL_NAME,
+  /* A local name.  The left subtree describes a function, and the
+     right subtree is a name which is local to that function.  */
+  DEMANGLE_COMPONENT_LOCAL_NAME,
+  /* A typed name.  The left subtree is a name, and the right subtree
+     describes that name as a function.  */
+  DEMANGLE_COMPONENT_TYPED_NAME,
+  /* A template.  The left subtree is a template name, and the right
+     subtree is a template argument list.  */
+  DEMANGLE_COMPONENT_TEMPLATE,
+  /* A template parameter.  This holds a number, which is the template
+     parameter index.  */
+  DEMANGLE_COMPONENT_TEMPLATE_PARAM,
+  /* A constructor.  This holds a name and the kind of
+     constructor.  */
+  DEMANGLE_COMPONENT_CTOR,
+  /* A destructor.  This holds a name and the kind of destructor.  */
+  DEMANGLE_COMPONENT_DTOR,
+  /* A vtable.  This has one subtree, the type for which this is a
+     vtable.  */
+  DEMANGLE_COMPONENT_VTABLE,
+  /* A VTT structure.  This has one subtree, the type for which this
+     is a VTT.  */
+  DEMANGLE_COMPONENT_VTT,
+  /* A construction vtable.  The left subtree is the type for which
+     this is a vtable, and the right subtree is the derived type for
+     which this vtable is built.  */
+  DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
+  /* A typeinfo structure.  This has one subtree, the type for which
+     this is the tpeinfo structure.  */
+  DEMANGLE_COMPONENT_TYPEINFO,
+  /* A typeinfo name.  This has one subtree, the type for which this
+     is the typeinfo name.  */
+  DEMANGLE_COMPONENT_TYPEINFO_NAME,
+  /* A typeinfo function.  This has one subtree, the type for which
+     this is the tpyeinfo function.  */
+  DEMANGLE_COMPONENT_TYPEINFO_FN,
+  /* A thunk.  This has one subtree, the name for which this is a
+     thunk.  */
+  DEMANGLE_COMPONENT_THUNK,
+  /* A virtual thunk.  This has one subtree, the name for which this
+     is a virtual thunk.  */
+  DEMANGLE_COMPONENT_VIRTUAL_THUNK,
+  /* A covariant thunk.  This has one subtree, the name for which this
+     is a covariant thunk.  */
+  DEMANGLE_COMPONENT_COVARIANT_THUNK,
+  /* A Java class.  This has one subtree, the type.  */
+  DEMANGLE_COMPONENT_JAVA_CLASS,
+  /* A guard variable.  This has one subtree, the name for which this
+     is a guard variable.  */
+  DEMANGLE_COMPONENT_GUARD,
+  /* A reference temporary.  This has one subtree, the name for which
+     this is a temporary.  */
+  DEMANGLE_COMPONENT_REFTEMP,
+  /* A standard substitution.  This holds the name of the
+     substitution.  */
+  DEMANGLE_COMPONENT_SUB_STD,
+  /* The restrict qualifier.  The one subtree is the type which is
+     being qualified.  */
+  DEMANGLE_COMPONENT_RESTRICT,
+  /* The volatile qualifier.  The one subtree is the type which is
+     being qualified.  */
+  DEMANGLE_COMPONENT_VOLATILE,
+  /* The const qualifier.  The one subtree is the type which is being
+     qualified.  */
+  DEMANGLE_COMPONENT_CONST,
+  /* The restrict qualifier modifying a member function.  The one
+     subtree is the type which is being qualified.  */
+  DEMANGLE_COMPONENT_RESTRICT_THIS,
+  /* The volatile qualifier modifying a member function.  The one
+     subtree is the type which is being qualified.  */
+  DEMANGLE_COMPONENT_VOLATILE_THIS,
+  /* The const qualifier modifying a member function.  The one subtree
+     is the type which is being qualified.  */
+  DEMANGLE_COMPONENT_CONST_THIS,
+  /* A vendor qualifier.  The left subtree is the type which is being
+     qualified, and the right subtree is the name of the
+     qualifier.  */
+  DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
+  /* A pointer.  The one subtree is the type which is being pointed
+     to.  */
+  DEMANGLE_COMPONENT_POINTER,
+  /* A reference.  The one subtree is the type which is being
+     referenced.  */
+  DEMANGLE_COMPONENT_REFERENCE,
+  /* A complex type.  The one subtree is the base type.  */
+  DEMANGLE_COMPONENT_COMPLEX,
+  /* An imaginary type.  The one subtree is the base type.  */
+  DEMANGLE_COMPONENT_IMAGINARY,
+  /* A builtin type.  This holds the builtin type information.  */
+  DEMANGLE_COMPONENT_BUILTIN_TYPE,
+  /* A vendor's builtin type.  This holds the name of the type.  */
+  DEMANGLE_COMPONENT_VENDOR_TYPE,
+  /* A function type.  The left subtree is the return type.  The right
+     subtree is a list of ARGLIST nodes.  Either or both may be
+     NULL.  */
+  DEMANGLE_COMPONENT_FUNCTION_TYPE,
+  /* An array type.  The left subtree is the dimension, which may be
+     NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an
+     expression.  The right subtree is the element type.  */
+  DEMANGLE_COMPONENT_ARRAY_TYPE,
+  /* A pointer to member type.  The left subtree is the class type,
+     and the right subtree is the member type.  CV-qualifiers appear
+     on the latter.  */
+  DEMANGLE_COMPONENT_PTRMEM_TYPE,
+  /* An argument list.  The left subtree is the current argument, and
+     the right subtree is either NULL or another ARGLIST node.  */
+  DEMANGLE_COMPONENT_ARGLIST,
+  /* A template argument list.  The left subtree is the current
+     template argument, and the right subtree is either NULL or
+     another TEMPLATE_ARGLIST node.  */
+  DEMANGLE_COMPONENT_TEMPLATE_ARGLIST,
+  /* An operator.  This holds information about a standard
+     operator.  */
+  DEMANGLE_COMPONENT_OPERATOR,
+  /* An extended operator.  This holds the number of arguments, and
+     the name of the extended operator.  */
+  DEMANGLE_COMPONENT_EXTENDED_OPERATOR,
+  /* A typecast, represented as a unary operator.  The one subtree is
+     the type to which the argument should be cast.  */
+  DEMANGLE_COMPONENT_CAST,
+  /* A unary expression.  The left subtree is the operator, and the
+     right subtree is the single argument.  */
+  DEMANGLE_COMPONENT_UNARY,
+  /* A binary expression.  The left subtree is the operator, and the
+     right subtree is a BINARY_ARGS.  */
+  DEMANGLE_COMPONENT_BINARY,
+  /* Arguments to a binary expression.  The left subtree is the first
+     argument, and the right subtree is the second argument.  */
+  DEMANGLE_COMPONENT_BINARY_ARGS,
+  /* A trinary expression.  The left subtree is the operator, and the
+     right subtree is a TRINARY_ARG1.  */
+  DEMANGLE_COMPONENT_TRINARY,
+  /* Arguments to a trinary expression.  The left subtree is the first
+     argument, and the right subtree is a TRINARY_ARG2.  */
+  DEMANGLE_COMPONENT_TRINARY_ARG1,
+  /* More arguments to a trinary expression.  The left subtree is the
+     second argument, and the right subtree is the third argument.  */
+  DEMANGLE_COMPONENT_TRINARY_ARG2,
+  /* A literal.  The left subtree is the type, and the right subtree
+     is the value, represented as a DEMANGLE_COMPONENT_NAME.  */
+  DEMANGLE_COMPONENT_LITERAL,
+  /* A negative literal.  Like LITERAL, but the value is negated.
+     This is a minor hack: the NAME used for LITERAL points directly
+     to the mangled string, but since negative numbers are mangled
+     using 'n' instead of '-', we want a way to indicate a negative
+     number which involves neither modifying the mangled string nor
+     allocating a new copy of the literal in memory.  */
+  DEMANGLE_COMPONENT_LITERAL_NEG
+};
+
+/* Types which are only used internally.  */
+
+struct demangle_operator_info;
+struct demangle_builtin_type_info;
+
+/* A node in the tree representation is an instance of a struct
+   demangle_component.  Note that the field names of the struct are
+   not well protected against macros defined by the file including
+   this one.  We can fix this if it ever becomes a problem.  */
+
+struct demangle_component
+{
+  /* The type of this component.  */
+  enum demangle_component_type type;
+
+  union
+  {
+    /* For DEMANGLE_COMPONENT_NAME.  */
+    struct
+    {
+      /* A pointer to the name (which need not NULL terminated) and
+        its length.  */
+      const char *s;
+      int len;
+    } s_name;
+
+    /* For DEMANGLE_COMPONENT_OPERATOR.  */
+    struct
+    {
+      /* Operator.  */
+      const struct demangle_operator_info *op;
+    } s_operator;
+
+    /* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR.  */
+    struct
+    {
+      /* Number of arguments.  */
+      int args;
+      /* Name.  */
+      struct demangle_component *name;
+    } s_extended_operator;
+
+    /* For DEMANGLE_COMPONENT_CTOR.  */
+    struct
+    {
+      /* Kind of constructor.  */
+      enum gnu_v3_ctor_kinds kind;
+      /* Name.  */
+      struct demangle_component *name;
+    } s_ctor;
+
+    /* For DEMANGLE_COMPONENT_DTOR.  */
+    struct
+    {
+      /* Kind of destructor.  */
+      enum gnu_v3_dtor_kinds kind;
+      /* Name.  */
+      struct demangle_component *name;
+    } s_dtor;
+
+    /* For DEMANGLE_COMPONENT_BUILTIN_TYPE.  */
+    struct
+    {
+      /* Builtin type.  */
+      const struct demangle_builtin_type_info *type;
+    } s_builtin;
+
+    /* For DEMANGLE_COMPONENT_SUB_STD.  */
+    struct
+    {
+      /* Standard substitution string.  */
+      const char* string;
+      /* Length of string.  */
+      int len;
+    } s_string;
+
+    /* For DEMANGLE_COMPONENT_TEMPLATE_PARAM.  */
+    struct
+    {
+      /* Template parameter index.  */
+      long number;
+    } s_number;
+
+    /* For other types.  */
+    struct
+    {
+      /* Left (or only) subtree.  */
+      struct demangle_component *left;
+      /* Right subtree.  */
+      struct demangle_component *right;
+    } s_binary;
+
+  } u;
+};
+
+/* People building mangled trees are expected to allocate instances of
+   struct demangle_component themselves.  They can then call one of
+   the following functions to fill them in.  */
+
+/* Fill in most component types with a left subtree and a right
+   subtree.  Returns non-zero on success, zero on failure, such as an
+   unrecognized or inappropriate component type.  */
+
+extern int
+cplus_demangle_fill_component PARAMS ((struct demangle_component *fill,
+                                      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));
+
+/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the
+   builtin type (e.g., "int", etc.).  Returns non-zero on success,
+   zero if the type is not recognized.  */
+
+extern int
+cplus_demangle_fill_builtin_type PARAMS ((struct demangle_component *fill,
+                                         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
+   used to disambiguate operators which can be both binary and unary,
+   such as '-').  Returns non-zero on success, zero if the operator is
+   not recognized.  */
+
+extern int
+cplus_demangle_fill_operator PARAMS ((struct demangle_component *fill,
+                                     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,
+   zero for bad arguments.  */
+
+extern int
+cplus_demangle_fill_extended_operator PARAMS ((struct demangle_component *fill,
+                                              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));
+
+/* 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));
+
+/* This function translates a mangled name into a struct
+   demangle_component tree.  The first argument is the mangled name.
+   The second argument is DMGL_* options.  This returns a pointer to a
+   tree on success, or NULL on failure.  On success, the third
+   argument is set to a block of memory allocated by malloc.  This
+   block should be passed to free when the tree is no longer
+   needed.  */
+
+extern struct demangle_component *
+cplus_demangle_v3_components PARAMS ((const char *mangled,
+                                     int options,
+                                     void **mem));
+
+/* This function takes a struct demangle_component tree and returns
+   the corresponding demangled string.  The first argument is DMGL_*
+   options.  The second is the tree to demangle.  The third is a guess
+   at the length of the demangled string, used to initially allocate
+   the return buffer.  The fourth is a pointer to a size_t.  On
+   success, this function returns a buffer allocated by malloc(), and
+   sets the size_t pointed to by the fourth argument to the size of
+   the allocated buffer (not the length of the returned string).  On
+   failure, this function returns NULL, and sets the size_t pointed to
+   by the fourth argument to 0 for an invalid tree, or to 1 for a
+   memory allocation error.  */
+
+extern char *
+cplus_demangle_print PARAMS ((int options,
+                             const struct demangle_component *tree,
+                             int estimated_length,
+                             size_t *p_allocated_size));
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* DEMANGLE_H */
diff --git a/Utils/impl/membind.hh b/Utils/impl/membind.hh
new file mode 100644 (file)
index 0000000..ef18500
--- /dev/null
@@ -0,0 +1,63 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+// NEVER INCLUDE DIRECTLY !! INCLUDE satcom/membind.hh
+
+#if !BOOST_PP_IS_ITERATING
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_shifted.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+
+template <typename R, typename T>
+boost::function<R()> membind(R (T::* fn)(),scOBTYPE ob)
+{
+    return boost::bind(fn,ob);
+}
+
+// for BOOST_PP_ITERATION() in 2..9 do
+#define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Utils/impl/membind.hh", 1))
+#include BOOST_PP_ITERATE()
+#elif BOOST_PP_ITERATION_DEPTH()==1 && BOOST_PP_ITERATION_FLAGS()==1
+// {{
+
+#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) )> 
+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++
+// End:
diff --git a/Utils/intrusive_refcount.cci b/Utils/intrusive_refcount.cci
new file mode 100644 (file)
index 0000000..a6a9d1a
--- /dev/null
@@ -0,0 +1,79 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of inline non-template functions
+
+//#include "intrusive_refcount.ih"
+
+// Custom includes
+#include <boost/assert.hpp>
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ satcom::lib::intrusive_refcount::refcount_t satcom::lib::intrusive_refcount::refcount()
+{
+    return refcount_;
+}
+
+prefix_ bool satcom::lib::intrusive_refcount::is_shared()
+{
+    return refcount()>1;
+}
+
+prefix_ satcom::lib::intrusive_refcount::intrusive_refcount()
+    : refcount_(0)
+{}
+
+prefix_  satcom::lib::intrusive_refcount::~intrusive_refcount()
+{}
+
+prefix_ void satcom::lib::intrusive_refcount::add_ref()
+{
+    ++refcount_;
+}
+
+prefix_ bool satcom::lib::intrusive_refcount::release()
+{
+    BOOST_ASSERT(refcount_>0);
+    return --refcount_ == 0;
+}
+
+prefix_ void satcom::lib::intrusive_ptr_add_ref(intrusive_refcount* p)
+{
+    p->add_ref();
+}
+
+prefix_ void satcom::lib::intrusive_ptr_release(intrusive_refcount* p)
+{
+    if (p->release())
+        delete p;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Utils/intrusive_refcount.hh b/Utils/intrusive_refcount.hh
new file mode 100644 (file)
index 0000000..a63dbe6
--- /dev/null
@@ -0,0 +1,76 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_intrusive_refcount_
+#define HH_intrusive_refcount_ 1
+
+// Custom includes
+#include <boost/utility.hpp>
+
+//#include "intrusive_refcount.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+    /** \brief
+     */
+    class intrusive_refcount
+        : public boost::noncopyable
+    {
+    public:
+        typedef unsigned refcount_t;
+
+        virtual ~intrusive_refcount();
+
+        refcount_t refcount();
+        bool is_shared();
+
+    protected:
+        intrusive_refcount();
+        
+    private:
+        void add_ref();
+        bool release();
+
+        refcount_t refcount_;
+
+        friend void satcom::lib::intrusive_ptr_add_ref(intrusive_refcount* p);
+        friend void satcom::lib::intrusive_ptr_release(intrusive_refcount* p);
+    };
+
+    void intrusive_ptr_add_ref(intrusive_refcount* p);
+    void intrusive_ptr_release(intrusive_refcount* p);
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "intrusive_refcount.cci"
+//#include "intrusive_refcount.ct"
+//#include "intrusive_refcount.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Utils/intrusive_refcount.test.cc b/Utils/intrusive_refcount.test.cc
new file mode 100644 (file)
index 0000000..f09e4bc
--- /dev/null
@@ -0,0 +1,84 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "intrusive_refcount.test.hh"
+//#include "intrusive_refcount.test.ih"
+
+// Custom includes
+#include "intrusive_refcount.hh"
+#include <boost/intrusive_ptr.hpp>
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    struct Tester 
+        : public satcom::lib::intrusive_refcount
+    {
+        typedef boost::intrusive_ptr<Tester> ptr;
+
+        Tester() { ++counter; }
+        ~Tester() { --counter; }
+
+        static unsigned counter;
+    };
+
+    unsigned Tester::counter = 0;
+}
+
+BOOST_AUTO_UNIT_TEST(intrusive_refcount)
+{
+    BOOST_CHECK_EQUAL(Tester::counter,0u);
+
+    Tester::ptr p (new Tester);
+    BOOST_CHECK_EQUAL(Tester::counter,1u);
+    BOOST_CHECK_EQUAL(p->refcount(),1u);
+    BOOST_CHECK_EQUAL(p->is_shared(),false);
+
+    {
+        Tester::ptr pp (p);
+        BOOST_CHECK_EQUAL(Tester::counter,1u);
+        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);
+
+    p = 0;
+    BOOST_CHECK_EQUAL(Tester::counter,0u);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/Utils/main.test.cc b/Utils/main.test.cc
new file mode 100644 (file)
index 0000000..fd4c97a
--- /dev/null
@@ -0,0 +1,43 @@
+// $Id: main.test.cc 32 2006-03-23 16:24:56Z sbund $
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+//#include "test.hh"
+//#include "test.ih"
+
+// Custom includes
+#define BOOST_AUTO_TEST_MAIN
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// End:
diff --git a/Utils/membind.hh b/Utils/membind.hh
new file mode 100644 (file)
index 0000000..e624e76
--- /dev/null
@@ -0,0 +1,54 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HH_membind_
+#define HH_membind_ 1
+
+// Custom includes
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace satcom {
+namespace lib {
+
+#define scOBTYPE T *
+#include "Utils/impl/membind.hh"
+#undef scOBTYPE
+
+#define scOBTYPE T &
+#include "Utils/impl/membind.hh"
+#undef scOBTYPE
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "membind.cci"
+//#include "membind.ct"
+//#include "membind.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// End:
diff --git a/Utils/membind.test.cc b/Utils/membind.test.cc
new file mode 100644 (file)
index 0000000..7c05954
--- /dev/null
@@ -0,0 +1,72 @@
+// $Id$
+//
+// Copyright (C) 2006 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Unit tests
+
+//#include "membind.test.hh"
+//#include "membind.test.ih"
+
+// Custom includes
+#include <sstream>
+#include <string>
+#include "Utils/membind.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    
+    struct Test {
+        char const * meth1() { 
+            return "meth1()";
+        }
+
+        std::string meth2(int foo, int bar) {
+            std::stringstream s;
+            s << "meth2(" << foo << "," << bar << ")";
+            return s.str();
+        }
+    };
+
+}
+
+BOOST_AUTO_UNIT_TEST(membind)
+{
+    Test instance;
+    boost::function<char const * ()> f1 (satcom::lib::membind(&Test::meth1,instance));
+    boost::function<std::string (int,int)> f2 (satcom::lib::membind(&Test::meth2,instance));
+
+    BOOST_CHECK_EQUAL( f1(), "meth1()" );
+    BOOST_CHECK_EQUAL( f2(1,2), "meth2(1,2)" );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// c-file-style: "satcom"
+// End:
diff --git a/satscons/BoostUnitTests.py b/satscons/BoostUnitTests.py
new file mode 100644 (file)
index 0000000..6976e12
--- /dev/null
@@ -0,0 +1,37 @@
+import SCons.Script.SConscript
+import SCons.Defaults
+import os.path
+import os
+
+def BoostUnitTests(env, target, source, test_source=None, LIBS = [], DEPENDS = [], **kw):
+    path, name = os.path.split(target)
+    if test_source:
+        if type(test_source) is not type([]):
+            test_source = [ test_source ]
+    else:
+        test_source = []
+    testEnv = env.Copy(**kw)
+    testEnv.Prepend(LIBS = '$BOOSTTESTLIB')
+    testEnv.Prepend(LIBS = LIBS)
+    sources = []
+    if source:
+        sources = sources + env.Object(source)
+    sources = sources + test_source
+    binName = os.path.join(path,'.' + os.path.splitext(name)[0]+'.bin')
+    testRunner = testEnv.Program(binName, sources)
+    stamp = os.path.join(path,'.' + os.path.splitext(name)[0]+'.stamp')
+    if DEPENDS:
+        env.Depends(testRunner, DEPENDS)
+    return env.Command([ target, stamp ], testRunner,
+                       [ '( $SOURCE $BOOSTTESTARGS 2>&1 && touch ${TARGETS[1]} ) | tee ${TARGETS[0]}' ])
+
+def dispatcher(*arg,**kw):
+    return BoostUnitTests(*arg,**kw)
+    
+def generate(env):
+    env['BOOSTTESTLIB'] = 'boost_unit_test_framework'
+    env['BOOSTTESTARGS'] = [ '--build_info=yes', '--log_level=test_suite' ]
+    env.__class__.BoostUnitTests = dispatcher
+
+def exists(env):
+    return 1
diff --git a/satscons/Doxyfile.template b/satscons/Doxyfile.template
new file mode 100644 (file)
index 0000000..3a08b63
--- /dev/null
@@ -0,0 +1,273 @@
+# Doxyfile 1.4.2
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = ""
+PROJECT_NUMBER         = "Version 0.0.1"
+OUTPUT_DIRECTORY       = doc
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = NO
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = YES
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = YES
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = NO
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = .
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.C \
+                         *.CC \
+                         *.C++ \
+                         *.II \
+                         *.I++ \
+                         *.H \
+                         *.HH \
+                         *.H++ \
+                         *.CS \
+                         *.PHP \
+                         *.PHP3 \
+                         *.M \
+                         *.MM \
+                         *.cci \
+                         *.ct \
+                         *.cti \
+                         *.ih
+RECURSIVE              = NO
+EXCLUDE                = doc
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = *.test.cc
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 5
+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        = satcom.css
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# 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  = 
+PREDEFINED             = DOXYGEN
+EXPAND_AS_DEFINED      = DefineCommand
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = NO
+HAVE_DOT               = YES
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = NO
+DIRECTORY_GRAPH        = NO
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 800
+MAX_DOT_GRAPH_HEIGHT   = 1200
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = YES
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = NO
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/satscons/Doxygen.py b/satscons/Doxygen.py
new file mode 100644 (file)
index 0000000..975bbe0
--- /dev/null
@@ -0,0 +1,31 @@
+import SCons.Script.SConscript
+import SCons.Builder
+import SCons.Defaults
+import os.path
+
+def replace_ext(n,ext):
+    base,ext = os.path.splitext(n)
+    return base+ext
+
+def Doxygen(env, target, source, image=[]):
+    path, name = os.path.split(str(target))
+    stamp = os.path.join(path, '.'+name+'.stamp')
+    dir = env.Dir(target)
+    env.Depends(dir,
+                [ env.Command(os.path.splitext(img)[0]+".png", img,
+                              [ 'TERM=dumb make -f imgconvert.mak $TARGET' ])
+                  for img in image ] +
+                [ env.Command(stamp, source,
+                              [ 'cd $TARGET.dir && $DOXYGENCOM',
+                                'cd $TARGET.dir/doc/html && (sed -ne \'1,/<table>/p\' <annotated.html && grep -F \'<tr>\' <annotated.html | sort -ft\'>\' -k4 && sed -ne \'/<\\/table>/,$$p\' <annotated.html) >annotated.html.new && mv annotated.html.new annotated.html',
+                                'touch $TARGET' ],
+                              source_scanner = SCons.Defaults.ObjSourceScan) ])
+    env.Clean(stamp, dir)
+    return dir
+
+def generate(env):
+    env['DOXYGENCOM'] = 'doxygen'
+    env.__class__.Doxygen = Doxygen
+
+def exists(env):
+    return 1
diff --git a/satscons/SConscript.template b/satscons/SConscript.template
new file mode 100644 (file)
index 0000000..771c9be
--- /dev/null
@@ -0,0 +1,10 @@
+Import('env')
+import SatSCons
+
+###########################################################################
+
+SatSCons.StandardTargets(env)
+
+# SatSCons.Lib(env,
+               library = 'Test',
+               sources = SatSCons.GlobSources())
diff --git a/satscons/SConstruct.template b/satscons/SConstruct.template
new file mode 100644 (file)
index 0000000..51e4564
--- /dev/null
@@ -0,0 +1,21 @@
+import sys, glob
+sys.path.append('satscons')
+import SatSCons
+
+###########################################################################
+
+SatSCons.UseBoost();
+SatSCons.UseSTLPort();
+SatSCons.UseDoxygen();
+env = SatSCons.MakeEnvironment();
+
+env.Append(
+   CPPPATH = [ '#' ]
+)
+
+Export('env')
+
+SConscript(glob.glob("*/SConscript"))
+
+SatSCons.StandardTargets(env)
+SatSCons.GlobalTargets(env)
diff --git a/satscons/SatSCons.py b/satscons/SatSCons.py
new file mode 100644 (file)
index 0000000..12eb6cf
--- /dev/null
@@ -0,0 +1,172 @@
+import os.path, SCons.Options, SCons.Environment, SCons.Script.SConscript, glob
+
+opts = None
+finalizers = []
+
+def InitOpts():
+    global opts
+    if opts is not None: return
+    opts = SCons.Options.Options('SConfig')
+    opts.Add('CXX', 'C++ compiler to use', 'g++')
+    opts.Add(SCons.Options.BoolOption('final','Enable optimization',0))
+
+def Finalizer(f):
+    global finalizers
+    finalizers.append(f)
+
+def UseBoost():
+    global opts
+    InitOpts()
+    opts.Add('BOOST_INCLUDES', 'Boost include directory', '')
+    opts.Add('BOOST_VARIANT', 'The boost variant to use', '')
+    opts.Add('BOOST_TOOLSET', 'The boost toolset to use', '')
+    opts.Add('BOOST_LIBDIR', 'The directory of the boost libraries', '')
+    Finalizer(FinalizeBoost)
+
+def FinalizeBoost(env):
+    env.Tool('BoostUnitTests', [os.path.split(__file__)[0]])
+
+    if env['BOOST_TOOLSET']:
+        runtime = ""
+        if not env['final'] : runtime += "gd"
+        if env['STLPORT_LIB'] : runtime += "p"
+        if runtime: runtime = "-" + runtime
+        env['BOOST_VARIANT'] = "-" + env['BOOST_TOOLSET'] + runtime
+
+    env['BOOSTTESTLIB'] = 'libboost_unit_test_framework' + env['BOOST_VARIANT']
+
+    env.Append(LIBPATH = [ '$BOOST_LIBDIR' ],
+               CPPPATH = [ '$BOOST_INCLUDES' ])
+
+def UseSTLPort():
+    global opts
+    InitOpts()
+    opts.Add('STLPORT_INCLUDES', 'STLport include directory', '')
+    opts.Add('STLPORT_LIB', 'Name of the stlport library or empty to not use stlport', '')
+    opts.Add('STLPORT_LIBDIR', 'The directory of the stlport libraries','')
+    Finalizer(FinalizeSTLPort)
+
+def FinalizeSTLPort(env):
+    env['STLPORT_DEBUGLIB'] = ''
+    if env['STLPORT_LIB']:
+        env['STLPORT_DEBUGLIB'] = env['STLPORT_LIB'] + '_stldebug'
+        env.Append(LIBPATH = [ '$STLPORT_LIBDIR' ],
+                   CPPPATH = [ '$STLPORT_INCLUDES' ])
+        if env['final']:
+            env.Append(LIBS = [ '$STLPORT_LIB' ])
+        else:
+            env.Append(LIBS = [ '$STLPORT_DEBUGLIB' ],
+                       CPPDEFINES = [ '_STLP_DEBUG' ])
+
+def UseDoxygen():
+    Finalizer(FinalizeDoxygen)
+
+def FinalizeDoxygen(env):
+    env.Tool('Doxygen', [os.path.split(__file__)[0]])
+    
+def MakeEnvironment():
+    global opts, finalizers
+    InitOpts()
+    env = SCons.Environment.Environment(options=opts)
+    if SCons.Script.SConscript.Arguments.get('final'):
+        env['final'] = 1
+    env.Help(opts.GenerateHelpText(env))
+    #conf = env.Configure()
+    #env = conf.env
+    if os.environ.has_key('SSH_AUTH_SOCK'):
+        env.Append( ENV = { 'SSH_AUTH_SOCK': os.environ['SSH_AUTH_SOCK'] } )
+
+    for finalizer in finalizers:
+        finalizer(env)
+
+    env.Append(CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long',
+                            '-pedantic', '-ansi' ],
+               LOCALLIBDIR = [ '#' ],
+               LIBPATH = [ '$LOCALLIBDIR' ])
+
+    if env['final']:
+        env.Append(CXXFLAGS = [ '-O3' ],
+                   CPPDEFINES = [ 'NDEBUG' ])
+    else:
+        env.Append(CXXFLAGS = [ '-O0', '-g', '-fno-inline' ],
+                        LINKFLAGS = [ '-g' ])
+
+    #return conf.Finish()
+    return env
+
+def GlobSources():
+    testSources = glob.glob("*.test.cc")
+    sources = [ x for x in glob.glob("*.cc") if x not in testSources ]
+    return (sources, testSources)
+    
+def StandardTargets(env):
+    all = env.Alias('all')
+    env.Clean(all, [ '.sconsign', '.sconf_temp', 'config.log', 'ChangeLog.bak', '.clean'
+                     ] + glob.glob("*~"))
+    env.Depends(all, '.')
+
+def GlobalTargets(env):
+    command = "find -name .svn -prune -o \( -name '*.hh' -o -name '*.ih' -o -name '*.cc' -o -name '*.cci' -o -name '*.ct' -o -name '*.cti' -o -name '*.mpp' \) -print " \
+              "| xargs -r awk -F '//' '/%s/{print ARGV[ARGIND] \":\" FNR \":\" $2}' > $TARGET"
+    env.AlwaysBuild(env.Command('TODOS',None,[ command % 'TODO' ]))
+    env.AlwaysBuild(env.Command('FIXMES',None,[ command % ' FIXME' ]))
+    env.AlwaysBuild(env.Command('BUGS',None,[ command % 'BUG' ] ))
+    env.Alias('status',[ 'TODOS', 'FIXMES', 'BUGS' ])
+
+def LibPath(lib): return '$LOCALLIBDIR/lib%s.a' % lib
+    
+def Objects(env, sources, testSources = None, LIBS = []):
+    if type(sources) == type(()):
+        testSources = sources[1]
+        sources = sources[0]
+
+    objects = None
+    if sources:
+        objects = env.Object(sources)
+
+    if testSources:
+        test = env.BoostUnitTests(
+            target = 'test.log',
+            source = sources,
+            test_source = testSources,
+            LIBS = LIBS,
+            DEPENDS = [ env.File(LibPath(x)) for x in LIBS ])
+        env.Alias('all_tests', test)
+        # Hmm ... here I'd like to use an Alias instead of a file
+        # however the alias does not seem to live in the subdirectory
+        # which breaks 'scons -u test'
+        env.Alias(env.File('test'), test)
+
+    return objects
+
+def Doxygen(env, sources, testSources = None):
+    if type(sources) == type(()):
+        testSources = sources[1]
+        sources = sources[0]
+
+    doc = env.Doxygen(
+        target = 'doc',
+        source = sources )
+
+    env.Alias('all_docs', doc)
+    return doc
+
+def Lib(env, library, sources, testSources = None, LIBS = []):
+    objects = Objects(env,sources,testSources,LIBS=LIBS)
+    lib = None
+    if objects:
+        lib = env.Library(env.File(LibPath(library)),objects)
+        env.Default(lib)
+        env.Append(ALLLIBS = library)
+    return lib
+
+def Binary(env, binary, sources, testSources = None, LIBS = []):
+    objects = Objects(env,sources,testSources,LIBS=LIBS)
+    program = None
+    if objects:
+        progEnv = env.Copy()
+        progEnv.Prepend(LIBS = LIBS)
+        program = progEnv.Program(target=binary,source=objects)
+        env.Default(program)
+        env.Depends(program, [ env.File(LibPath(x)) for x in LIBS ])
+    return program
diff --git a/satscons/__init__.py b/satscons/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/satscons/nodeglob.py b/satscons/nodeglob.py
new file mode 100644 (file)
index 0000000..feb19ba
--- /dev/null
@@ -0,0 +1,28 @@
+import fnmatch
+import os
+
+def glob(match):
+    """Similar to glob.glob, except globs SCons nodes, and thus sees
+    generated files and files from build directories.  Basically, it sees
+    anything SCons knows about.  A key subtlety is that since this function
+    operates on generated nodes as well as source nodes on the filesystem,
+    it needs to be called after builders that generate files you want to
+    include."""
+    def fn_filter(node):
+        fn = str(node)
+        return fnmatch.fnmatch(os.path.basename(fn), match)
+
+    here = Dir('.')
+
+    children = here.all_children()
+    nodes = map(File, filter(fn_filter, children))
+    node_srcs = [n.srcnode() for n in nodes]
+
+    src = here.srcnode()
+    if src is not here:
+        src_children = map(File, filter(fn_filter, src.all_children()))
+        for s in src_children:
+            if s not in node_srcs:
+                nodes.append(File(os.path.basename(str(s))))
+
+    return nodes
diff --git a/satscons/pdflatex.py b/satscons/pdflatex.py
new file mode 100644 (file)
index 0000000..bbb129b
--- /dev/null
@@ -0,0 +1,99 @@
+import SCons.Defaults
+
+import md5, os.path
+import SCons.Action, SCons.Builder, SCons.Util, SCons.Errors, SCons.Environment
+
+PDFLaTeXAction = SCons.Action.CommandAction("$PDFLATEXCOM")
+
+# copied from Action.py ... changed to tage explicit path-names as
+# target/source instead of node objects
+def my_executeCommand(cmd_list, target, source, env):
+    import SCons.Util 
+    escape = env.get('ESCAPE', lambda x: x)
+    if env.has_key('SHELL'): shell = env['SHELL']
+    else: raise SCons.Errors.UserError('Missing SHELL construction variable.')
+    if env.has_key('PIPE_BUILD'):
+        pipe_build = 1
+        if env.has_key('PSPAWN'): pspawn = env['PSPAWN']
+        else: raise SCons.Errors.UserError('Missing PSPAWN construction variable.')
+        if env.has_key('PSTDOUT'): pstdout = env['PSTDOUT']
+        else: raise SCons.Errors.UserError('Missing PSTDOUT construction variable.')
+        if env.has_key('PSTDERR'): pstderr = env['PSTDERR']
+        else: raise SCons.Errors.UserError('Missing PSTDOUT construction variable.')
+    else:
+        pipe_build = 0
+        if env.has_key('SPAWN'): spawn = env['SPAWN']
+        else: raise SCons.Errors.UserError('Missing SPAWN construction variable.')
+    # Here, replaced the source and target argumnets with a dict argument
+    cmd_list = env.subst_list(cmd_list, 0, dict = { 'TARGET': target, 'TARGETS': [ target ],
+                                                    'SOURCE': source, 'SOURCES': [ source ] })
+    for cmd_line in cmd_list:
+        if len(cmd_line):
+            try: ENV = env['ENV']
+            except KeyError:
+                global default_ENV
+                if not default_ENV:
+                    import SCons.Environment
+                    default_ENV = SCons.Environment.Environment()['ENV']
+                ENV = default_ENV
+            for key, value in ENV.items():
+                if SCons.Util.is_List(value):
+                    value = SCons.Util.flatten(value)
+                    ENV[key] = string.join(map(str, value), os.pathsep)
+                elif not SCons.Util.is_String(value):
+                    ENV[key] = str(value)
+            cmd_line = SCons.Util.escape_list(cmd_line, escape)
+            if pipe_build: ret = pspawn( shell, escape, cmd_line[0], cmd_line,
+                                         ENV, pstdout, pstderr )
+            else: ret = spawn(shell, escape, cmd_line[0], cmd_line, ENV)
+            if ret: return ret
+    return 0
+
+def TeXchecksum(files):
+    m = md5.new()
+    for f in files:
+        try:
+            m.update(file(f,"rb").read())
+        except IOError: pass
+    return m.digest()
+
+def TeXPdfAction(target, source, env):
+    src = os.path.abspath(str(source[0]))
+    path, pdf = os.path.split(str(target[0]))
+    base, ext = os.path.splitext(pdf)
+    cwd = os.getcwd()
+    if path: os.chdir(path)
+    checkfiles = [ base + ext for ext in env["TEXCHECKEXT"] ]
+    checksum = TeXchecksum(checkfiles)
+    rv = 0
+    for i in range(env["TEXMAXRECURSE"]+1):
+        if i==env["TEXMAXRECURSE"]:
+            print "\nWARNING: TeX recursion depth exceeded. They generated file may not be final.\n"
+            break
+        rv = my_executeCommand("$PDFLATEXCOM", pdf, src, env)
+        if rv: break
+        new_checksum = TeXchecksum(checkfiles)
+        if new_checksum == checksum: break
+        checksum = new_checksum
+    os.chdir(cwd)
+    return rv
+
+class TeXPdfBuilder(SCons.Builder.BuilderBase) :
+    def __call__(self, env, target = None, source = SCons.Builder._null, **kw):
+        tlist = SCons.Builder.BuilderBase.__call__(self, env, target, source, **kw)
+        exts = env["TEXCHECKEXT"] + env["TEXCLEANEXT"]
+        for t in tlist:
+            base, ext = os.path.splitext(str(t))
+            for ext in exts:
+                env.Clean(t,base+ext)
+        return tlist
+
+
+def generate(env):
+    env['TEXCHECKEXT'] = [ '.aux', '.toc' ]
+    env['TEXCLEANEXT'] = [ '.log', '.dvi' ]
+    env['TEXMAXRECURSE'] = 5
+    env['BUILDERS']['PDF'] = TeXPdfBuilder(action = TeXPdfAction, suffix='.pdf')
+
+def exists(env):
+    return 1
diff --git a/satscons/satconf.py b/satscons/satconf.py
new file mode 100644 (file)
index 0000000..bf67150
--- /dev/null
@@ -0,0 +1,2 @@
+import SCons.Options, SCons.SConf, SCons.Environment
+