Packets/80221Bundle: more GenericTLVBase integration; removed GenericTLVPacket; some...
tho [Wed, 14 Oct 2009 12:50:40 +0000 (12:50 +0000)]
Packets/PacketParserBase: added protect() member; thx g0dil

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1496 270642c3-0616-0410-b53a-bc976706d245

15 files changed:
senf/Packets/80221Bundle/MIHPacket.cc
senf/Packets/80221Bundle/MIHPacket.hh
senf/Packets/80221Bundle/MIHPacket.test.cc
senf/Packets/80221Bundle/MIHTypes.cci [moved from senf/Packets/80221Bundle/MIHPacket.cci with 73% similarity]
senf/Packets/80221Bundle/MIHTypes.hh [new file with mode: 0644]
senf/Packets/80221Bundle/TLVPacket.cci [deleted file]
senf/Packets/80221Bundle/TLVParser.cc [moved from senf/Packets/80221Bundle/TLVPacket.cc with 74% similarity]
senf/Packets/80221Bundle/TLVParser.cci [new file with mode: 0644]
senf/Packets/80221Bundle/TLVParser.hh [moved from senf/Packets/80221Bundle/TLVPacket.hh with 63% similarity]
senf/Packets/80221Bundle/TLVParser.test.cc [moved from senf/Packets/80221Bundle/TLVPacket.test.cc with 63% similarity]
senf/Packets/GenericTLV.ct
senf/Packets/GenericTLV.cti
senf/Packets/GenericTLV.hh
senf/Packets/PacketParser.cci
senf/Packets/PacketParser.hh

index c1a151d..409f9b8 100644 (file)
@@ -144,16 +144,28 @@ prefix_ senf::PacketInterpreterBase::factory_t senf::MIHPacketType::nextPacketTy
     if (p.data().size() < initSize())
         return no_factory();
     PkReg_Entry const * e (PacketRegistry<MIHMessageRegistry>::lookup( p->messageId(), nothrow ));
-    return e ? e->factory() : MIHPayloadPacket::factory();
+    return e ? e->factory() : MIHGenericPayloadPacket::factory();
 }
 
-prefix_ void senf::MIHPayloadPacketType::dump(packet p, std::ostream &os)
+///////////////////////////////////////////////////////////////////////////
+// MIHGenericPayloadPacketType
+
+prefix_ void senf::MIHGenericPayloadPacketType::dump(packet p, std::ostream &os)
 {
     boost::io::ios_all_saver ias(os);
     os << "MIH Payload (service specific TLVs):\n"
        << "  ToDo!\n";
 }
 
+prefix_ void senf::MIHGenericPayloadPacketType::finalize(packet p)
+{
+    typedef parser::tlv_list_t::container tlvContainer_t;
+    tlvContainer_t tlvs (p->tlv_list() );
+    for (tlvContainer_t::iterator i (tlvs.begin()); i != tlvs.end(); ++i)
+        i->finalizeLength();
+}
+
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
 
index 1d1c226..e9f6f3c 100644 (file)
 
 // Custom includes
 #include <senf/Packets/Packets.hh>
-#include <senf/Socket/Protocols/Raw/MACAddress.hh>
-#include <senf/Socket/Protocols/INet/INet4Address.hh>
-#include <senf/Socket/Protocols/INet/INet6Address.hh>
-#include "TLVPacket.hh"
-#include <boost/function_output_iterator.hpp>
-#include <boost/iterator/filter_iterator.hpp>
-#include <boost/variant.hpp>
-
+#include "TLVParser.hh"
 
 //#include "MIHPacket.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -51,121 +44,7 @@ namespace senf {
         SENF_PACKET_REGISTRY_REGISTER(                                    \
             senf::MIHMessageRegistry, packet::type::MESSAGE_ID, packet )
     
-    class MIHFId 
-        : public boost::variant< boost::blank, senf::MACAddress, senf::INet4Address, 
-                senf::INet6Address, std::string, senf::EUI64 >,
-          public boost::less_than_comparable<MIHFId>,
-          public boost::equality_comparable<MIHFId>
-    {
-    public:
-        enum Type { Empty, MACAddress, INet4Address, INet6Address, String, EUI64 };
-      
-        MIHFId();                                   ///< Create empty instance.
-        MIHFId(senf::MACAddress const & addr);      ///< Construct id with given MACAddress 
-        MIHFId(senf::INet4Address const & addr);    ///< Construct id with given INet4Address
-        MIHFId(senf::INet6Address const & addr);    ///< Construct id with given INet6Address
-        MIHFId(std::string const & addr);           ///< Construct id with given String
-        MIHFId(senf::EUI64 const & addr);           ///< Construct id with given EUI64
-        
-        Type type() const;
-        bool operator==(MIHFId const & other) const;
-        bool operator<(MIHFId const & other) const; 
-        
-    private:
-        struct GetTypeVisitor : public boost::static_visitor<Type> {
-            Type operator()(boost::blank const &) const { return Empty; }
-            Type operator()(senf::MACAddress const &) const { return MACAddress; }
-            Type operator()(senf::INet4Address const &) const { return INet4Address; }
-            Type operator()(senf::INet6Address const &) const { return INet6Address; }
-            Type operator()(std::string const & ) const { return String; }
-            Type operator()(senf::EUI64 const &) const { return EUI64; }
-        };
-        struct EqualsVisitor : public boost::static_visitor<bool> {
-            template <typename T, typename U>
-            bool operator()(T const &, U const &) const {
-                return false;
-            }
-            template <typename T>
-            bool operator()( const T & lhs, const T & rhs ) const {
-                return lhs == rhs;
-            }
-        };
-        struct LessThanVisitor : public boost::static_visitor<bool> {
-            template <typename T, typename U>
-            bool operator()(T const &, U const &) const {
-                return false;
-            }
-            template <typename T>
-            bool operator()( const T & lhs, const T & rhs ) const {
-                return lhs < rhs;
-            }
-        };
-    };
-    
-    
-    /** \brief Parse a MIHF_ID
-
-         the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
-         we could set maxLengthValue in init(), but for the most MIHF_IDs the default
-         maximum length of 127 should be enough.
-         
-         \note you must call mihfIdPacket.maxLengthValue( 253) *before*
-         setting longer MIHF_IDs values.
-    */
-    class MIHFId_TLVParser : public MIHBaseTLVParser
-    {
-    #   include SENF_PARSER()
-        SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
-        SENF_PARSER_SKIP     ( length(), 0      );
-        SENF_PARSER_FINALIZE ( MIHFId_TLVParser );
-        
-    public:
-        std::string asString() const;
-        void setString(std::string const &id);
-
-        senf::MACAddress asMACAddress() const;
-        void setMACAddress(senf::MACAddress const &mac);
-
-        senf::INet4Address asINet4Address() const;
-        void setINet4Address(senf::INet4Address const &addr);
-
-        senf::INet6Address asINet6Address() const;
-        void setINet6Address(senf::INet6Address const &addr);
-        
-        senf::EUI64 asEUI64() const;
-        void setEUI64(senf::EUI64 const &addr);
-
-        MIHFId valueAs(MIHFId::Type type) const;
-        
-    private:
-        template <class OutputIterator>
-        struct binaryNAIEncoder {
-            binaryNAIEncoder(OutputIterator &i) : i_(i) {}
-            void operator()(const boost::uint8_t &v) const {
-                *i_++ = '\\';
-                *i_++ = v;
-            }
-            OutputIterator &i_;
-        };
-        template <class OutputIterator>
-        static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> > getNAIEncodedOutputIterator(OutputIterator i) {
-            return boost::make_function_output_iterator(binaryNAIEncoder<OutputIterator>(i));
-        }
-
-        struct binaryNAIDecoder {
-            binaryNAIDecoder() : readNextByte_(true) {}
-            bool operator()(const boost::uint8_t &v) {
-                readNextByte_ = readNextByte_ ? false : true;
-                return readNextByte_;
-            }
-            bool readNextByte_;
-        };
-        template <class Iterator>
-        static boost::filter_iterator<binaryNAIDecoder, Iterator> getNAIDecodedIterator(Iterator begin, Iterator end) {
-            return boost::make_filter_iterator<binaryNAIDecoder>(begin, end);
-        }
-    };
+     
     /** \brief Parse a MIH packet
 
         Parser implementing the MIH header. The fields implemented are:
@@ -244,42 +123,47 @@ namespace senf {
         static factory_t nextPacketType(packet p);
     };
 
-    /** \brief MIH packet typedef */
+    /** \brief MIH packet typedef
+        \ingroup protocolbundle_80221
+     */
     typedef ConcretePacket<MIHPacketType> MIHPacket;
 
 
-    struct MIHPayloadPacketParser : public PacketParserBase
+    struct MIHGenericPayloadPacketParser : public PacketParserBase
     {
     #   include SENF_PARSER()
-        SENF_PARSER_LIST ( tlv_list, packetSize(), MIHGenericTLVPacketParser );
-        SENF_PARSER_FINALIZE ( MIHPayloadPacketParser );
+        SENF_PARSER_LIST ( tlv_list, packetSize(), MIHGenericTLVParser );
+        SENF_PARSER_FINALIZE ( MIHGenericPayloadPacketParser );
     };
 
-    struct MIHPayloadPacketType
+    struct MIHGenericPayloadPacketType
         : public PacketTypeBase,
-          public PacketTypeMixin<MIHPayloadPacketType>
+          public PacketTypeMixin<MIHGenericPayloadPacketType>
     {
 #ifndef DOXYGEN
-        typedef PacketTypeMixin<MIHPayloadPacketType> mixin;
+        typedef PacketTypeMixin<MIHGenericPayloadPacketType> mixin;
 #endif
-        typedef ConcretePacket<MIHPayloadPacketType> packet; ///< MIH Payload packet typedef
-        typedef MIHPayloadPacketParser parser; ///< typedef to the parser of MIH Payload packet
+        typedef ConcretePacket<MIHGenericPayloadPacketType> packet; ///< MIH Payload packet typedef
+        typedef MIHGenericPayloadPacketParser parser; ///< typedef to the parser of MIH Payload packet
 
         using mixin::nextPacketRange;
         using mixin::init;
         using mixin::initSize;
 
-        /** \brief Dump given MIHPayload in readable form to given output stream */
+        /** \brief Dump given MIHGenericPayload in readable form to given output stream */
         static void dump(packet p, std::ostream &os);
+        static void finalize(packet p);
     };
 
-     /** \brief MIH Payload packet typedef */
-    typedef ConcretePacket<MIHPayloadPacketType> MIHPayloadPacket;
+     /** \brief MIH Payload packet typedef
+         \ingroup protocolbundle_80221
+      */
+    typedef ConcretePacket<MIHGenericPayloadPacketType> MIHGenericPayloadPacket;
 }
 
 
 ///////////////////////////////hh.e////////////////////////////////////////
-#include "MIHPacket.cci"
+//#include "MIHPacket.cci"
 //#include "MIHPacket.ct"
 //#include "MIHPacket.cti"
 #endif
index 31a7cdb..1a84a82 100644 (file)
@@ -234,18 +234,19 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_parse)
     MIHPacket mihPacket (MIHPacket::create(data));
     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 42u);
 
-    BOOST_REQUIRE( mihPacket.next().is<MIHPayloadPacket>() );
-    MIHPayloadPacket mihPayload (mihPacket.next().as<MIHPayloadPacket>());
+    BOOST_REQUIRE( mihPacket.next().is<MIHGenericPayloadPacket>() );
+    MIHGenericPayloadPacket mihPayload (mihPacket.next().as<MIHGenericPayloadPacket>());
 
     BOOST_CHECK_EQUAL( mihPayload->tlv_list().size(), 2u);
-    MIHPayloadPacketParser::tlv_list_t::container tlv_list_container (mihPayload->tlv_list());
+    MIHGenericPayloadPacket::Parser::tlv_list_t::container tlv_list_container (
+            mihPayload->tlv_list());
 
-    MIHGenericTLVPacket::Parser tlv1 = *tlv_list_container.begin();
+    MIHGenericTLVParser tlv1 = *tlv_list_container.begin();
     BOOST_CHECK_EQUAL( tlv1.type(), 0x42);
     BOOST_CHECK_EQUAL( tlv1.length(), 0x0au);
     BOOST_CHECK_EQUAL( tlv1.value().size(), 0x0a);
 
-    MIHGenericTLVPacket::Parser tlv2 = *boost::next(tlv_list_container.begin());
+    MIHGenericTLVParser tlv2 = *boost::next(tlv_list_container.begin());
     BOOST_CHECK_EQUAL( tlv2.type(), 0x43);
     BOOST_CHECK_EQUAL( tlv2.length(), 0x05u);
     BOOST_CHECK_EQUAL( tlv2.value().size(), 0x05);
@@ -260,23 +261,21 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_create)
     mihPacket->src_mihfId().setString( "senf@berlios.de");
     mihPacket->dst_mihfId().setString( "test");
 
-    MIHPayloadPacket mihPayload (MIHPayloadPacket::createAfter(mihPacket));
-
+    MIHGenericPayloadPacket mihPayload (MIHGenericPayloadPacket::createAfter(mihPacket));
+    MIHGenericPayloadPacket::Parser::tlv_list_t::container tlvContainer (
+            mihPayload->tlv_list() );
+    
     unsigned char tlv1_value[] = {
-            0x1a, 0x2b, 0x3c, 0x4d, 0x5e };
-    MIHGenericTLVPacket tlv2 = (MIHGenericTLVPacket::create());
-    tlv2->type() = 0x43;
-    tlv2->value( tlv1_value);
-    tlv2.finalizeThis();
-    mihPayload->tlv_list().push_front( tlv2);
+           0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+    MIHGenericTLVParser tlv1 ( tlvContainer.push_back_space());
+    tlv1.type() = 0x42;
+    tlv1.value( tlv1_value);
 
     unsigned char tlv2_value[] = {
-           0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
-    MIHGenericTLVPacket tlv1 (MIHGenericTLVPacket::create());
-    tlv1->type() = 0x42;
-    tlv1->value( tlv2_value);
-    tlv1.finalizeThis();
-    mihPayload->tlv_list().push_front( tlv1);
+            0x1a, 0x2b, 0x3c, 0x4d, 0x5e };
+    MIHGenericTLVParser tlv2 ( tlvContainer.push_back_space());
+    tlv2.type() = 0x43;
+    tlv2.value( tlv2_value);
 
     mihPacket.finalizeAll();
 
similarity index 73%
rename from senf/Packets/80221Bundle/MIHPacket.cci
rename to senf/Packets/80221Bundle/MIHTypes.cci
index 00a70bf..33b8cab 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief MIH protocol inline non-template implementation */
+    \brief MIHTypes inline non-template implementation */
 
-//#include "MIHPacket.ih"
+//#include "MIHTypes.ih"
 
 // Custom includes
 
 #define prefix_ inline
-///////////////////////////////cci.p////////////////////////////////////////
+///////////////////////////////cci.p///////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////
 // MIHFId
@@ -81,53 +81,17 @@ prefix_ bool senf::MIHFId::operator<(senf::MIHFId const & other)
     return boost::apply_visitor( LessThanVisitor(), *this, other);
 }
 
-///////////////////////////////////////////////////////////////////////////
-// MIHFId_TLVParser
-
-prefix_ std::string senf::MIHFId_TLVParser::asString()
-    const
-{
-    return std::string( i(1+length_().bytes()), i(1+length_().bytes()+length()) );
-}
-
-prefix_ senf::MACAddress senf::MIHFId_TLVParser::asMACAddress()
-    const
-{
-    return MACAddress::from_data( 
-            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+12) ));
-}
 
-prefix_ senf::INet4Address senf::MIHFId_TLVParser::asINet4Address()
-    const
-{
-    return INet4Address::from_data( 
-            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+8) ));
-}
-
-prefix_ senf::INet6Address senf::MIHFId_TLVParser::asINet6Address()
-    const
-{
-    return INet6Address::from_data( 
-            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+32) ));
-}
-
-prefix_ senf::EUI64 senf::MIHFId_TLVParser::asEUI64()
-    const
-{
-    return EUI64::from_data( 
-            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+16) ));
-}
-
-///////////////////////////////cci.e////////////////////////////////////////
+///////////////////////////////cci.e///////////////////////////////////////
 #undef prefix_
 
 \f
 // Local Variables:
 // mode: c++
 // fill-column: 100
+// comment-column: 40
 // c-file-style: "senf"
 // indent-tabs-mode: nil
 // ispell-local-dictionary: "american"
 // compile-command: "scons -u test"
-// comment-column: 40
 // End:
diff --git a/senf/Packets/80221Bundle/MIHTypes.hh b/senf/Packets/80221Bundle/MIHTypes.hh
new file mode 100644 (file)
index 0000000..ea8b5b2
--- /dev/null
@@ -0,0 +1,110 @@
+// $Id$
+//
+// Copyright (C) 2009
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Thorsten Horstmann <tho@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief MIHTypes public header */
+
+#ifndef HH_SENF_Packets_80221Bundle_MIHTypes_
+#define HH_SENF_Packets_80221Bundle_MIHTypes_ 1
+
+// Custom includes
+#include <senf/Socket/Protocols/Raw/MACAddress.hh>
+#include <senf/Socket/Protocols/INet/INet4Address.hh>
+#include <senf/Socket/Protocols/INet/INet6Address.hh>
+#include <boost/function_output_iterator.hpp>
+#include <boost/iterator/filter_iterator.hpp>
+#include <boost/variant.hpp>
+
+//#include "MIHTypes.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+    class MIHFId 
+        : public boost::variant< boost::blank, senf::MACAddress, senf::INet4Address, 
+                senf::INet6Address, std::string, senf::EUI64 >,
+          public boost::less_than_comparable<MIHFId>,
+          public boost::equality_comparable<MIHFId>
+    {
+    public:
+        enum Type { Empty, MACAddress, INet4Address, INet6Address, String, EUI64 };
+      
+        MIHFId();                                   ///< Create empty instance.
+        MIHFId(senf::MACAddress const & addr);      ///< Construct id with given MACAddress 
+        MIHFId(senf::INet4Address const & addr);    ///< Construct id with given INet4Address
+        MIHFId(senf::INet6Address const & addr);    ///< Construct id with given INet6Address
+        MIHFId(std::string const & addr);           ///< Construct id with given String
+        MIHFId(senf::EUI64 const & addr);           ///< Construct id with given EUI64
+        
+        Type type() const;
+        bool operator==(MIHFId const & other) const;
+        bool operator<(MIHFId const & other) const; 
+        
+    private:
+        struct GetTypeVisitor : public boost::static_visitor<Type> {
+            Type operator()(boost::blank const &) const { return Empty; }
+            Type operator()(senf::MACAddress const &) const { return MACAddress; }
+            Type operator()(senf::INet4Address const &) const { return INet4Address; }
+            Type operator()(senf::INet6Address const &) const { return INet6Address; }
+            Type operator()(std::string const & ) const { return String; }
+            Type operator()(senf::EUI64 const &) const { return EUI64; }
+        };
+        struct EqualsVisitor : public boost::static_visitor<bool> {
+            template <typename T, typename U>
+            bool operator()(T const &, U const &) const {
+                return false;
+            }
+            template <typename T>
+            bool operator()( const T & lhs, const T & rhs ) const {
+                return lhs == rhs;
+            }
+        };
+        struct LessThanVisitor : public boost::static_visitor<bool> {
+            template <typename T, typename U>
+            bool operator()(T const &, U const &) const {
+                return false;
+            }
+            template <typename T>
+            bool operator()( const T & lhs, const T & rhs ) const {
+                return lhs < rhs;
+            }
+        };
+    };
+
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "MIHTypes.cci"
+//#include "MIHTypes.ct"
+//#include "MIHTypes.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/senf/Packets/80221Bundle/TLVPacket.cci b/senf/Packets/80221Bundle/TLVPacket.cci
deleted file mode 100644 (file)
index 17a2c76..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// $Id$
-//
-// Copyright (C) 2007
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-//     Thorsten Horstmann <tho@berlios.de>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-/** \file
-    \brief TLVPacket inline non-template implementation */
-
-//#include "TLVPacket.ih"
-
-// Custom includes
-
-#define prefix_ inline
-///////////////////////////////cci.p////////////////////////////////////////
-
-prefix_ senf::MIHTLVLengthParser::size_type senf::MIHTLVLengthParser::bytes() const 
-{
-    return 1 + ( length_field()<=128 ? 0 : fixed_length_field());
-}
-
-prefix_ void senf::MIHGenericTLVPacketType::finalize(packet p)
-{
-    p->finalizeLength();
-}
-
-///////////////////////////////cci.e////////////////////////////////////////
-#undef prefix_
-
-\f
-// Local Variables:
-// mode: c++
-// fill-column: 100
-// c-file-style: "senf"
-// indent-tabs-mode: nil
-// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
-// comment-column: 40
-// End:
similarity index 74%
rename from senf/Packets/80221Bundle/TLVPacket.cc
rename to senf/Packets/80221Bundle/TLVParser.cc
index e37c1a0..43ba4c2 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief TLVPacket non-inline non-template implementation */
+    \brief TLVParser non-inline non-template implementation */
 
-#include "TLVPacket.hh"
-//#include "TLVPacket.ih"
+#include "TLVParser.hh"
+//#include "TLVParser.ih"
 
 // Custom includes
 #include <iomanip>
@@ -33,6 +33,9 @@
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
+///////////////////////////////////////////////////////////////////////////
+// MIHBaseTLVParser
+
 prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
         MIHTLVLengthParser::value_type size) 
 {
@@ -48,6 +51,9 @@ prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
 }
 
 
+///////////////////////////////////////////////////////////////////////////
+// MIHTLVLengthParser
+
 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const 
 {
     switch (bytes() ) {
@@ -135,22 +141,22 @@ prefix_ void senf::MIHTLVLengthParser::finalize()
     value_type v = value();
     size_type b = bytes();
     if (v <= 128) {
-        if (b != 1) resize(1);
+        if (b != 1) resize_(1);
         return;
     }
     if (v <= UInt8Parser::max_value + 128) {
-        if (b != 2) resize(2);
+        if (b != 2) resize_(2);
         return;
     }
     if (v <= UInt16Parser::max_value + 128) {
-        if (b != 3) resize(3);
+        if (b != 3) resize_(3);
         return;
     }
     if (v <= UInt24Parser::max_value + 128 ) {
-        if (b != 4) resize(4);
+        if (b != 4) resize_(4);
         return;
     }
-    if (b != 5) resize(5);
+    if (b != 5) resize_(5);
 }
 
 
@@ -160,60 +166,32 @@ prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type
         return;
     size_type b = bytes();
     if (v <= UInt8Parser::max_value + 128) {
-        if (b < 2) resize(2);
+        if (b < 2) resize_(2);
         return;
     }
     if (v <= UInt16Parser::max_value + 128) {
-        if (b < 3) resize(3);
+        if (b < 3) resize_(3);
         return;
     }
     if (v <= UInt24Parser::max_value + 128) {
-        if (b < 4) resize(4);
+        if (b < 4) resize_(4);
         return;
     }
-    if (b < 5) resize(5);
+    if (b < 5) resize_(5);
 }
 
 
-prefix_ void senf::MIHTLVLengthParser::resize(size_type size)
+prefix_ void senf::MIHTLVLengthParser::resize_(size_type size)
 {
     value_type v = value();
-    size_type current_size (bytes());
-    SafePacketParserWrapper<MIHTLVLengthParser> safeThis (*this);
-    
-    if (current_size > size)
-        data().erase( i(), boost::next(i(), current_size-size));
-    else
-        data().insert( i(), size-current_size, 0);
-    
+    resize(bytes(), size);
     if (size > 1) {
-        safeThis->extended_length_flag() = true;
-        safeThis->fixed_length_field() = size - 1;
+        extended_length_flag() = true;
+        fixed_length_field() = size - 1;
     } else {
-        safeThis->extended_length_flag() = false;
+        extended_length_flag() = false;
     }
-    safeThis->value(v);
-}
-
-
-//prefix_ senf::PacketInterpreterBase::range senf::MIHGenericTLVPacketParser::value() 
-//    const
-//{
-//    senf::PacketData::iterator begin (boost::next(data().begin(), 1 + length_().bytes() ));
-//    return PacketInterpreterBase::range(
-//            begin, boost::next( begin, length()) );
-//}
-
-
-prefix_ void senf::MIHGenericTLVPacketType::dump(packet p, std::ostream & os)
-{
-    boost::io::ios_all_saver ias(os);
-    os << "MIH GenericTLV Packet:\n"
-       << std::dec
-       << senf::fieldName("type")                      << unsigned( p->type()) << "\n"
-       << senf::fieldName("length")                    << unsigned( p->length()) << "\n"
-       << "  value:\n";
-    senf::hexdump( p->value().begin(), p->value().end(), os);
+    value(v);
 }
 
 
diff --git a/senf/Packets/80221Bundle/TLVParser.cci b/senf/Packets/80221Bundle/TLVParser.cci
new file mode 100644 (file)
index 0000000..467a732
--- /dev/null
@@ -0,0 +1,90 @@
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Thorsten Horstmann <tho@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief TLVParser inline non-template implementation */
+
+//#include "TLVParser.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// MIHTLVLengthParser
+
+prefix_ senf::MIHTLVLengthParser::size_type senf::MIHTLVLengthParser::bytes() const 
+{
+    return 1 + ( length_field()<=128 ? 0 : fixed_length_field());
+}
+
+///////////////////////////////////////////////////////////////////////////
+// MIHFId_TLVParser
+
+prefix_ std::string senf::MIHFId_TLVParser::asString()
+    const
+{
+    return std::string( i(1+length_().bytes()), i(1+length_().bytes()+length()) );
+}
+
+prefix_ senf::MACAddress senf::MIHFId_TLVParser::asMACAddress()
+    const
+{
+    return MACAddress::from_data( 
+            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+12) ));
+}
+
+prefix_ senf::INet4Address senf::MIHFId_TLVParser::asINet4Address()
+    const
+{
+    return INet4Address::from_data( 
+            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+8) ));
+}
+
+prefix_ senf::INet6Address senf::MIHFId_TLVParser::asINet6Address()
+    const
+{
+    return INet6Address::from_data( 
+            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+32) ));
+}
+
+prefix_ senf::EUI64 senf::MIHFId_TLVParser::asEUI64()
+    const
+{
+    return EUI64::from_data( 
+            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+16) ));
+}
+
+///////////////////////////////cci.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End:
similarity index 63%
rename from senf/Packets/80221Bundle/TLVPacket.hh
rename to senf/Packets/80221Bundle/TLVParser.hh
index bcaecae..1ee9bfa 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief TLVPacket public header */
+    \brief TLVParser public header */
 
-#ifndef HH_SENF_Packets_80221Bundle_TLVPacket_
-#define HH_SENF_Packets_80221Bundle_TLVPacket_ 1
+#ifndef HH_SENF_Packets_80221Bundle_TLVParser_
+#define HH_SENF_Packets_80221Bundle_TLVParser_ 1
 
 // Custom includes
 #include <algorithm>
 #include <senf/Packets/Packets.hh>
+#include "MIHTypes.hh"
 
-//#include "TLVPacket.mpp"
+//#include "TLVParser.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
@@ -71,14 +72,15 @@ namespace senf {
         void finalize();
         void maxValue(value_type v);
         value_type maxValue() const;
+        
     private:
-        void resize(size_type size);
+        void resize_(size_type size);
     };  
         
 
-    /** \brief Base class for TLV-Packet-Parsers
+    /** \brief Base class for MIH TLV parsers
      
-         MIHBaseTLVParser is the abstract base class for TLV-Packet-Parsers. It defines the
+         MIHBaseTLVParser is the abstract base class for MIH TLV parsers. It defines the
          \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a 
          MIHTLVLengthParser. The length field is read-only. 
          
@@ -92,14 +94,6 @@ namespace senf {
              SENF_PARSER_VECTOR  ( value, bytes(length), senf::MACAddressParser );
              SENF_PARSER_FINALIZE( MacAddressesTLVParser );
          };
-         
-         struct MacAddressesTLVPacketType : public PacketTypeBase {
-            typedef MacAddressesTLVParser parser;
-            ...
-            static void finalize(ConcretePacket<MacAddressesTLVPacketType> p) { 
-                p->finalizeLength();
-            }
-         };
          \endcode
          
          You have to adjust the maximum length value with the \ref maxLengthValue function 
@@ -108,7 +102,7 @@ namespace senf {
          if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before.
          
          \see MIHTLVLengthParser \n
-           MIHGenericTLVPacketParser \n
+           MIHGenericTLVParser \n
      */
     class MIHBaseTLVParser : public PacketParserBase
     {
@@ -124,7 +118,7 @@ namespace senf {
             \param v maximum value of length field
          */
         void maxLengthValue(MIHTLVLengthParser::value_type v) const {
-            length_().maxValue(v);
+            protect(), length_().maxValue(v);
         }
         
         /** \brief shrink size of length field to minimum
@@ -133,7 +127,7 @@ namespace senf {
             the current length value.
          */
         void finalizeLength() { 
-            length_().finalize(); 
+            protect(), length_().finalize(); 
         };
         
     protected:
@@ -143,62 +137,92 @@ namespace senf {
 
         
     /** \brief Parser for a generic TLV packet
-
-        \see MIHGenericTLVPacketType
      */
-    struct MIHGenericTLVPacketParser 
+    struct MIHGenericTLVParser
         : public GenericTLVParserBase<MIHBaseTLVParser>
     {
         typedef senf::GenericTLVParserBase<MIHBaseTLVParser> base;
-        MIHGenericTLVPacketParser(data_iterator i, state_type s) : base(i,s) {}
+        MIHGenericTLVParser(data_iterator i, state_type s) : base(i,s) {}
 
         void init() const {
             defaultInit();
             maxLengthValue( MIHTLVLengthParser::max_value);
-        }        
+        }
+        
+        using base::init;
     };
-    
-    /** \brief Generic TLV packet
+        
+    /** \brief Parse a MIHF_ID
+
+         the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
+         we could set maxLengthValue in init(), but for the most MIHF_IDs the default
+         maximum length of 127 should be enough.
+         
+         \note you must call mihfIdPacket.maxLengthValue( 253) *before*
+         setting longer MIHF_IDs values.
+    */
+    class MIHFId_TLVParser : public MIHBaseTLVParser
+    {
+    #   include SENF_PARSER()
+        SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
+        SENF_PARSER_SKIP     ( length(), 0      );
+        SENF_PARSER_FINALIZE ( MIHFId_TLVParser );
+        
+    public:
+        std::string asString() const;
+        void setString(std::string const &id);
+
+        senf::MACAddress asMACAddress() const;
+        void setMACAddress(senf::MACAddress const &mac);
 
-        \par Packet type (typedef):
-            \ref MIHGenericTLVPacket
+        senf::INet4Address asINet4Address() const;
+        void setINet4Address(senf::INet4Address const &addr);
 
-        \image html TLV.png
+        senf::INet6Address asINet6Address() const;
+        void setINet6Address(senf::INet6Address const &addr);
         
-        \ingroup protocolbundle_80221
-     */
-    struct MIHGenericTLVPacketType
-        : public PacketTypeBase,
-          public PacketTypeMixin<MIHGenericTLVPacketType>
-    {
-#ifndef DOXYGEN
-        typedef PacketTypeMixin<MIHGenericTLVPacketType> mixin;
-#endif
-        typedef ConcretePacket<MIHGenericTLVPacketType> packet; ///< GenericTLV packet typedef
-        typedef MIHGenericTLVPacketParser parser;               ///< typedef to the parser of GenericTLV packet
+        senf::EUI64 asEUI64() const;
+        void setEUI64(senf::EUI64 const &addr);
 
-        using mixin::nextPacketRange;
-        using mixin::init;
-        using mixin::initSize;
+        MIHFId valueAs(MIHFId::Type type) const;
         
-        /** \brief Dump given MIHGenericTLVPacket in readable form to given output stream */
-        static void dump(packet p, std::ostream & os);  
-        static void finalize(packet p);  ///< Finalize packet.
-                                         /**< shrink size of length field to minimum 
-                                              \see MIHBaseTLVParser::finalizeLength() */
+    private:
+        template <class OutputIterator>
+        struct binaryNAIEncoder {
+            binaryNAIEncoder(OutputIterator &i) : i_(i) {}
+            void operator()(const boost::uint8_t &v) const {
+                *i_++ = '\\';
+                *i_++ = v;
+            }
+            OutputIterator &i_;
+        };
+        template <class OutputIterator>
+        static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> > getNAIEncodedOutputIterator(OutputIterator i) {
+            return boost::make_function_output_iterator(binaryNAIEncoder<OutputIterator>(i));
+        }
+
+        struct binaryNAIDecoder {
+            binaryNAIDecoder() : readNextByte_(true) {}
+            bool operator()(const boost::uint8_t &v) {
+                readNextByte_ = readNextByte_ ? false : true;
+                return readNextByte_;
+            }
+            bool readNextByte_;
+        };
+        template <class Iterator>
+        static boost::filter_iterator<binaryNAIDecoder, Iterator> getNAIDecodedIterator(Iterator begin, Iterator end) {
+            return boost::make_filter_iterator<binaryNAIDecoder>(begin, end);
+        }
     };
-    
-    /** \brief GenericTLV packet typedef
-        \ingroup protocolbundle_80221
-     */
-    typedef ConcretePacket<MIHGenericTLVPacketType> MIHGenericTLVPacket;
+
+
 }
 
 
 ///////////////////////////////hh.e////////////////////////////////////////
-#include "TLVPacket.cci"
-//#include "TLVPacket.ct"
-//#include "TLVPacket.cti"
+#include "TLVParser.cci"
+//#include "TLVParser.ct"
+//#include "TLVParser.cti"
 #endif
 
 \f
similarity index 63%
rename from senf/Packets/80221Bundle/TLVPacket.test.cc
rename to senf/Packets/80221Bundle/TLVParser.test.cc
index 9743718..bea19dd 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief TLVPacket unit tests */
+    \brief TLVParser unit tests */
 
-//#include "TLVPacket.test.hh"
-//#include "TLVPacket.test.ih"
+//#include "TLVParser.test.hh"
+//#include "TLVParser.test.ih"
 
 // Custom includes
-#include "TLVPacket.hh"
+#include "TLVParser.hh"
 #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
 
 #include <senf/Utils/auto_unit_test.hh>
 using namespace senf;
 
 namespace {
-
-#define CHECK_TLVPacket(tlvPacket, ptype, plength)                            \
-{                                                                             \
-    BOOST_CHECK_EQUAL( tlvPacket->type(),         ptype   );                  \
-    BOOST_CHECK_EQUAL( tlvPacket->length(),       plength );                  \
-    BOOST_CHECK_EQUAL( tlvPacket->value().size(), int(plength) );             \
-    std::ostringstream oss (std::ostringstream::out);                         \
-    SENF_CHECK_NO_THROW( tlvPacket.dump( oss));                               \
-    senf::PacketData::iterator dataIterator (tlvPacket->value().begin());     \
-    for (unsigned i=0; i<plength; i++) {                                      \
-        BOOST_CHECK_EQUAL( *dataIterator, i );                                \
-        dataIterator++;                                                       \
-    }                                                                         \
+    struct VoidPacket : public PacketTypeBase
+    {};
+                           
+#define CHECK_TLVParser(tlvParser, ptype, plength)                          \
+{                                                                           \
+    BOOST_CHECK_EQUAL( tlvParser.type(),         ptype   );                 \
+    BOOST_CHECK_EQUAL( tlvParser.length(),       plength );                 \
+    BOOST_CHECK_EQUAL( tlvParser.value().size(), int(plength) );            \
+    senf::PacketData::iterator dataIterator (tlvParser.value().begin());    \
+    for (unsigned i=0; i<plength; i++) {                                    \
+        BOOST_CHECK_EQUAL( *dataIterator, i );                              \
+        dataIterator++;                                                     \
+    }                                                                       \
 }
 }
 
 
-BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_parse_packet_with_simple_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_simple_length)
 {
-    unsigned char data[] = {
+    PacketInterpreterBase::byte data[] = {
         0x01, // type
         0x0A, // first bit not set, length=10
         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
     };
-    MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create(data));
-    CHECK_TLVPacket( tlvPacket, 0x01, 0x0Au );
+    PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(data));
+    MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
+    CHECK_TLVParser( tlvParser, 0x01, 0x0Au );
 }
 
 
-BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_parse_packet_with_extended_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_extended_length)
 {
-    unsigned char data[] = {
+    PacketInterpreterBase::byte data[] = {
         0x01, // type
         0x81, // first and last bit set => one byte length following
         0x0A, // length (10 = 138 bytes value follows)
@@ -89,73 +90,76 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_parse_packet_with_extended_length)
         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 
         0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89
     };
-    MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create(data));
-    CHECK_TLVPacket( tlvPacket, 0x01, 0x8au );
+    PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(data));
+    MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
+    CHECK_TLVParser( tlvParser, 0x01, 0x8au );
 }
 
 
-BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_packet_with_simple_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_simple_length)
 {
-    unsigned char value[] = {
+    PacketInterpreterBase::byte value[] = {
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
     };
-    MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create());
-    tlvPacket->type() = 42u;
-    tlvPacket->value( value);
-    tlvPacket.finalizeThis();
+    PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(2u));
+    MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
+    tlvParser.type() = 42u;
+    tlvParser.value( value);
+    tlvParser.finalizeLength();
 
-    CHECK_TLVPacket( tlvPacket, 42u, 0x0Au );
+    CHECK_TLVParser( tlvParser, 42u, 0x0Au );
 
-    unsigned char data[] = {
+    PacketInterpreterBase::byte data[] = {
         0x2a, // type
         0x0A, // first bit not set, length=10
         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
     };
-    BOOST_CHECK( equal( tlvPacket.data().begin(), tlvPacket.data().end(), data ));
+    SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
+            p->data().begin(), p->data().end() );
 }
 
 
-BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_packet_with_extended_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_extended_length)
 {
-    unsigned char value[255];
+    PacketInterpreterBase::byte value[255];
     for (unsigned i=0; i<sizeof(value); i++)
         value[i] = i;
-    MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create());
-    tlvPacket->maxLengthValue( MIHTLVLengthParser::max_value);
-    SENF_CHECK_NO_THROW( tlvPacket->type() = 42u);
-    SENF_CHECK_NO_THROW( tlvPacket->value( value));
-    SENF_CHECK_NO_THROW( tlvPacket.finalizeThis());
+    PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(2u));
+    MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
+    tlvParser.maxLengthValue( MIHTLVLengthParser::max_value);
+    tlvParser.type() = 42u;
+    tlvParser.value( value);
+    tlvParser.finalizeLength();
 
-    CHECK_TLVPacket( tlvPacket, 42u, sizeof(value) );
+    CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
 
-    unsigned char data[] = {
+    PacketInterpreterBase::byte data[] = {
         0x2a, // type
         0x81, // first and last bit set => one byte length following
         0x7f, // length (127 = 255 bytes value)
         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // first bytes of value
     };
-    BOOST_CHECK( equal(
-            tlvPacket.data().begin(),
-            boost::next( tlvPacket.data().begin(), sizeof(data)),
-            data ));
+    SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
+            p->data().begin(), boost::next( p->data().begin(), sizeof(data)) );
 }
 
 
-BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_invalid_packet)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid)
 {
-    MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create());
-    tlvPacket->type() = 42u;
-    tlvPacket.finalizeThis();
+    PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(2u));
+    MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
+    tlvParser.type() = 42u;
+    tlvParser.finalizeLength();
 
-    unsigned char value[255];
+    PacketInterpreterBase::byte value[255];
     for (unsigned i=0; i<sizeof(value); i++)
         value[i] = i;
 
-    BOOST_CHECK_THROW( tlvPacket->value( value), MIHTLVLengthException);
-    tlvPacket->maxLengthValue( sizeof(value));
-    tlvPacket->value( value);
-    tlvPacket.finalizeThis();
-    CHECK_TLVPacket( tlvPacket, 42u, sizeof(value) );
+    BOOST_CHECK_THROW( tlvParser.value( value), MIHTLVLengthException);
+    tlvParser.maxLengthValue( sizeof(value));
+    tlvParser.value( value);
+    tlvParser.finalizeLength();
+    CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
 }
 
 
index 75debb1..110b3ed 100644 (file)
@@ -56,10 +56,8 @@ template <class Base>
 template <class ForwardReadableRange>
 prefix_ void senf::GenericTLVParserBase<Base>::value_(ForwardReadableRange const &range)
 {
-    unsigned int rangeSize = boost::size(range);
-    std::cerr << "GenericTLVParserBase<Base>::value_() rangeSize=" << 
-            unsigned( rangeSize) << " length()=" << unsigned( this->length()) << " bytes(self)=" << 
-            unsigned( senf::bytes(self())) << " bytes()=" << unsigned( senf::bytes(*this)) << std::endl;
+    //typename boost::range_difference<ForwardReadableRange>::type rangeSize ( boost::size(range));
+    unsigned rangeSize ( boost::size(range));
     if ( rangeSize != this->length() )
         resize( bytes(), rangeSize + senf::bytes(self()) );
     std::copy( boost::begin(range), boost::end(range), boost::next(
index de01ab2..a5d39b5 100644 (file)
@@ -46,6 +46,7 @@ prefix_ void senf::GenericTLVParserBase<Base>::init()
 template <class Base>
 template <class Parser>
 prefix_ Parser senf::GenericTLVParserBase<Base>::as()
+    const
 {
     return Parser(this->i(), this->state() );
 }
@@ -53,6 +54,7 @@ prefix_ Parser senf::GenericTLVParserBase<Base>::as()
 template <class Base>
 template <class Parser>
 prefix_ bool senf::GenericTLVParserBase<Base>::is()
+    const
 {
     return this->type().value() == Parser::TYPEID;
 }
index 3c4f12d..6f89e82 100644 (file)
@@ -124,7 +124,7 @@ namespace senf {
         \endcode  
 
         \see 
-            IPv6GenericOptionTLVParser, WLANGenericInfoElementParser, MIHGenericTLVPacketParser 
+            IPv6GenericOptionTLVParser, WLANGenericInfoElementParser, MIHGenericTLVParser 
      */
     template <class Base>
     class GenericTLVParserBase : public Base
@@ -140,10 +140,10 @@ namespace senf {
         Parser init();
         
         template <class Parser>
-        Parser as();
+        Parser as() const;
         
         template <class Parser>
-        bool is();
+        bool is() const;
 
         senf::PacketInterpreterBase::range value() const;
         
index 510c2a6..0fa3347 100644 (file)
@@ -49,8 +49,29 @@ prefix_ senf::PacketParserBase::data_iterator senf::PacketParserBase::end()
     return data_->end();
 }
 
+prefix_ senf::PacketParserBase::ParserProtector::ParserProtector(PacketParserBase const * p)
+    : safe_i_( *p), parser_(p) 
+{}
+
+prefix_ senf::PacketParserBase::ParserProtector::ParserProtector(ParserProtector const & other_)
+    : safe_i_( *other_.parser_), parser_(other_.parser_) 
+{
+    other_.parser_ = 0;
+}
+
+prefix_ senf::PacketParserBase::ParserProtector::~ParserProtector() 
+{ 
+    if (parser_) const_cast<PacketParserBase *>(parser_)->i_ = safe_i_; 
+}
+
 // protected members
 
+prefix_ senf::PacketParserBase::ParserProtector senf::PacketParserBase::protect()
+    const
+{ 
+    return ParserProtector(this); 
+}
+
 prefix_ bool senf::PacketParserBase::check(size_type size)
     const
 {
index e22bf18..3eb5d6a 100644 (file)
 #include "PacketTypes.hh"
 #include "PacketData.hh"
 #include "ParseHelpers.hh"
+#include "SafeIterator.hh"
 
 //#include "PacketParser.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -290,7 +291,21 @@ namespace senf {
                                              implementation. Re-implement this member in your own
                                              parsers if needed. */
 
+    private:
+        struct ParserProtector {
+            senf::safe_data_iterator safe_i_;
+            mutable PacketParserBase const * parser_;
+            
+            ParserProtector( PacketParserBase const * parser);
+            ParserProtector(ParserProtector const & other_);
+            ~ParserProtector();
+            
+            template <class _>
+            void operator()(_ const &) const {}
+        };
     protected:
+        ParserProtector protect() const;
+        
         PacketParserBase(data_iterator i, state_type s); ///< Standard constructor
                                         /**< This is the constructor used by most parsers. The
                                              parameters are just forwarded from the derived classes
@@ -371,6 +386,7 @@ namespace senf {
         PacketData * data_;
 
         template <class Parser> friend class SafePacketParserWrapper;
+        friend class ParserProtector;
     };
 
     /** \brief Return raw size parsed by the given parser object