Packets/80221Bundle: added classes for list TLV parsers
tho [Wed, 13 Jan 2010 10:35:08 +0000 (10:35 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1541 270642c3-0616-0410-b53a-bc976706d245

senf/Packets/80221Bundle/TLVParser.cc
senf/Packets/80221Bundle/TLVParser.cci
senf/Packets/80221Bundle/TLVParser.ct [new file with mode: 0644]
senf/Packets/80221Bundle/TLVParser.hh
senf/Packets/80221Bundle/TLVParser.test.cc

index db7ef8b..ca70a1c 100644 (file)
@@ -40,6 +40,16 @@ SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHStatusTLVParser );
 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHValidTimeIntervalTLVParser );
 
 ///////////////////////////////////////////////////////////////////////////
+// senf::MIHBaseListTLVParser
+
+prefix_ void senf::MIHBaseListTLVParser::maxListSize(MIHTLVLengthParser::value_type maxl)
+    const
+{
+    protect(), listSize_().capacity( maxl);
+    maxLength( maxl + senf::bytes(listSize_()));
+}
+
+///////////////////////////////////////////////////////////////////////////
 // senf::MIHFIdTLVParser
 
 prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
@@ -56,17 +66,18 @@ prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
 prefix_ void senf::MIHFIdTLVParser::finalize()
 {
     protect(), idLength_().finalize();
-    length_() << idLength() + idLength_().bytes();
+    length_() << idLength() + senf::bytes(idLength_());
     MIHBaseTLVParser::finalize();
 }
 
-prefix_ void senf::MIHFIdTLVParser::maxIdLength(boost::uint8_t maxLength)
+prefix_ void senf::MIHFIdTLVParser::maxIdLength(boost::uint8_t maxl)
+    const
 {
     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
-    if (maxLength > 253) 
+    if (maxl > 253) 
         throw std::length_error("maximum length of a MIHF_ID is 253 octets");
-    protect(), idLength_().maxValue( maxLength);
-    maxLengthValue( maxLength + senf::bytes(idLength_()));
+    protect(), idLength_().capacity( maxl);
+    maxLength( maxl + senf::bytes(idLength_()));
 }
 
 prefix_ senf::safe_data_iterator senf::MIHFIdTLVParser::resizeValueField(
@@ -286,7 +297,7 @@ prefix_ void senf::MIHTLVLengthParser::value(value_type const & v)
     underflow_flag() = (v <= 128);
 }
 
-prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue()
+prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::capacity()
     const
 {
     switch (bytes() ) {
@@ -340,7 +351,7 @@ prefix_ void senf::MIHTLVLengthParser::finalize()
     if (b != 5) resize_(5);
 }
 
-prefix_ void senf::MIHTLVLengthParser::maxValue(MIHTLVLengthParser::value_type v)
+prefix_ void senf::MIHTLVLengthParser::capacity(MIHTLVLengthParser::value_type v)
 {
     if (v <= 128)
         return;
index b7bc869..982b75f 100644 (file)
@@ -141,6 +141,20 @@ prefix_ bool senf::MIHFIdTLVParser::valueEquals( MIHFId const & id)
 }
 
 
+///////////////////////////////////////////////////////////////////////////
+// MIHBaseTLVParser
+
+prefix_ void senf::MIHBaseTLVParser::maxLength(MIHTLVLengthParser::value_type maxl) 
+    const
+{
+    protect(), length_().capacity(maxl);
+}
+
+prefix_ void senf::MIHBaseTLVParser::finalize() 
+{
+    protect(), length_().finalize();
+};
+
 
 ///////////////////////////////cci.e////////////////////////////////////////
 #undef prefix_
diff --git a/senf/Packets/80221Bundle/TLVParser.ct b/senf/Packets/80221Bundle/TLVParser.ct
new file mode 100644 (file)
index 0000000..9302c1f
--- /dev/null
@@ -0,0 +1,58 @@
+// $Id$
+//
+// Copyright (C) 2010
+// 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 non-inline template implementation */
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::MIHListTLVParserMixin
+
+template <class Self>
+prefix_ void senf::MIHListTLVParserMixin<Self>::finalize()
+{
+    Self * self ( static_cast<Self *>(this));
+    self->protect(), self->listSize_().finalize();
+    typename Self::length_t::value_type size ( 
+            senf::bytes(self->listSize_()) + senf::bytes(self->value()));
+    self->maxLength( size);
+    self->length_() << size;
+}
+
+            
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index f04adff..4f017cb 100644 (file)
@@ -70,8 +70,8 @@ namespace senf {
         SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field,   6,  unsigned );
 
         void finalize();
-        void maxValue(value_type v);
-        value_type maxValue() const;
+        void capacity(value_type v);
+        value_type capacity() const;
         
     private:
         void resize_(size_type size);
@@ -96,10 +96,10 @@ namespace senf {
          };
          \endcode
          
-         You have to adjust the maximum length value with the \ref maxLengthValue function 
+         You have to adjust the maximum length value with the \ref maxLength function 
          before the length value is set. The default maximum value is 128. So, in the above
          example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
-         if you don't call \c maxLengthValue( \e some_value) before.
+         if you don't call \c maxLength( \e some_value) before.
          
          \see MIHTLVLengthParser \n
            MIHGenericTLVParser \n
@@ -112,25 +112,22 @@ namespace senf {
         SENF_PARSER_FIELD_RO ( length, MIHTLVLengthParser );
         SENF_PARSER_FINALIZE ( MIHBaseTLVParser           );
         
-        /** \brief set maximum value of length field
-    
-            The size of the length field will be increased if necessary.
-            \param v maximum value of length field
-         */
-        void maxLengthValue(MIHTLVLengthParser::value_type v) const {
-            protect(), length_().maxValue(v);
-        }
-        
-        /** \brief shrink size of length field to minimum
+        /** \brief shrink size of the TLV length field to minimum
     
             The size of the length field will be decreased to minimum necessary to hold
             the current length value.
          */
-        void finalize() { 
-            protect(), length_().finalize();
-        };
+        void finalize();
     
         typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
+        
+    protected:
+        /** \brief set maximum value of TLV length field
+    
+            The size of the length field will be increased if necessary.
+            \param v maximum value of length field
+         */
+        void maxLength(MIHTLVLengthParser::value_type maxl) const;
     };
 
     
@@ -145,16 +142,38 @@ namespace senf {
 
         void init() const {
             defaultInit();
-            maxLengthValue( MIHTLVLengthParser::max_value);
+            maxLength( MIHTLVLengthParser::max_value);
         }
         
         using base::init;
+        using base::maxLength;
+    };
+        
+        
+    /** \brief Base class for list TLV parser
+     */ 
+    struct MIHBaseListTLVParser 
+        : public MIHBaseTLVParser
+    {
+    #   include SENF_PARSER()
+        SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
+        SENF_PARSER_FIELD_RO ( listSize, MIHTLVLengthParser );
+        SENF_PARSER_FINALIZE ( MIHBaseListTLVParser );
+
+        void maxListSize(MIHTLVLengthParser::value_type maxl) const;
+    };
+
+    template <class Self>
+    struct MIHListTLVParserMixin
+    {
+        void finalize();            
     };
         
     /** \brief Parse a MIHF_ID
 
          Note that 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
+         We could set maxLength in init(), but for the most MIHF_IDs the default
          maximum length of 128 should be enough.
          
          \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer
@@ -206,7 +225,7 @@ namespace senf {
         ///@}
         
         void dump(std::ostream & os) const;
-        void maxIdLength(boost::uint8_t maxLength);
+        void maxIdLength(boost::uint8_t maxl) const;
         void finalize();
 
     private:
@@ -350,7 +369,7 @@ namespace senf {
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "TLVParser.cci"
-//#include "TLVParser.ct"
+#include "TLVParser.ct"
 #include "TLVParser.cti"
 #endif
 
index 4b949b7..2c213c4 100644 (file)
@@ -128,7 +128,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_extended_length)
     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(
             senf::PacketInterpreterBase::size_type(2u)));
     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
-    tlvParser.maxLengthValue( MIHTLVLengthParser::max_value);
+    tlvParser.maxLength( MIHTLVLengthParser::max_value);
     tlvParser.type() = 42u;
     tlvParser.value( value);
     tlvParser.finalize();
@@ -159,7 +159,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid)
         value[i] = i;
 
     BOOST_CHECK_THROW( tlvParser.value( value), MIHTLVLengthException);
-    tlvParser.maxLengthValue( sizeof(value));
+    tlvParser.maxLength( sizeof(value));
     tlvParser.value( value);
     tlvParser.finalize();
     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );