--- /dev/null
+SConfig
+.doc.stamp
+.test.stamp
+.sconf_temp
+.sconsign
+config.log
+doc
+test
+structure.png
+.clean
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+# 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
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+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.
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+Import('env')
+import SatSCons
+
+###########################################################################
+
+sources = SatSCons.GlobSources()
+SatSCons.StandardTargets(env)
+SatSCons.Lib(env, 'Packets', sources)
+SatSCons.Doxygen(env,sources)
--- /dev/null
+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
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+
+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:
--- /dev/null
+// $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:
--- /dev/null
+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;
+}
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+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"
--- /dev/null
+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)
--- /dev/null
+Import('env')
+import SatSCons
+
+###########################################################################
+
+SatSCons.StandardTargets(env)
+SatSCons.Lib(env,
+ library = 'Scheduler',
+ sources = SatSCons.GlobSources(),
+ LIBS = [ 'Utils' ])
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+# 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
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+Import('env')
+import SatSCons
+
+###########################################################################
+
+sources = SatSCons.GlobSources()
+
+SatSCons.StandardTargets(env)
+
+SatSCons.Lib(env,
+ library = 'Socket',
+ sources = sources,
+ LIBS = [ 'Utils' ])
+
+SatSCons.Doxygen(env,sources)
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+Import('env')
+import SatSCons
+
+###########################################################################
+
+SatSCons.StandardTargets(env)
+SatSCons.Lib(env, 'Utils', SatSCons.GlobSources())
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+/* 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 */
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+// $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:
--- /dev/null
+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
--- /dev/null
+# 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
--- /dev/null
+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
--- /dev/null
+Import('env')
+import SatSCons
+
+###########################################################################
+
+SatSCons.StandardTargets(env)
+
+# SatSCons.Lib(env,
+ library = 'Test',
+ sources = SatSCons.GlobSources())
--- /dev/null
+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)
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+import SCons.Options, SCons.SConf, SCons.Environment
+