diff --git a/Packets/DefaultBundle/Doxyfile b/Packets/DefaultBundle/Doxyfile index c221a91ceb18e89c2543a3f0259dc2fd77f94441..3507c83188922c74b01fff89fb28dfd2fc65bcec 100644 --- a/Packets/DefaultBundle/Doxyfile +++ b/Packets/DefaultBundle/Doxyfile @@ -4,3 +4,4 @@ PROJECT_NAME = DefaultBundle TAGFILES = "$(TOPDIR)/Utils/doc/Utils.tag" "$(TOPDIR)/Packets/doc/Packets.tag" GENERATE_TAGFILE = doc/DefaultBundle.tag INPUT = . +ALPHABETICAL_INDEX = NO diff --git a/Packets/MPEGDVBBundle/Doxyfile b/Packets/MPEGDVBBundle/Doxyfile index db2a4692c3307552fb31442b6094c60e5231cb97..a53939d7ebb33fea1407e3f8c0078156609cdd46 100644 --- a/Packets/MPEGDVBBundle/Doxyfile +++ b/Packets/MPEGDVBBundle/Doxyfile @@ -4,3 +4,4 @@ PROJECT_NAME = MPEGDVBBundle TAGFILES = "$(TOPDIR)/Utils/doc/Utils.tag" "$(TOPDIR)/Packets/doc/Packets.tag" GENERATE_TAGFILE = doc/MPEGDVBBundle.tag INPUT = . +ALPHABETICAL_INDEX = NO diff --git a/Packets/PacketRegistry.ih b/Packets/PacketRegistry.ih index 7ea93c85e6ad193051368d2d540d57bd707c00f9..77d75981835fbb323637666c4b6835f25f30af5f 100644 --- a/Packets/PacketRegistry.ih +++ b/Packets/PacketRegistry.ih @@ -45,7 +45,8 @@ namespace detail { virtual Packet::factory_t factory() const; }; - /** \brief Internal + /** \brief Internal: Singleton class implementing the packet registry. + \internal */ template <class KeyType> diff --git a/Packets/ParseArray.hh b/Packets/ParseArray.hh index f0669b3e20cb7c7006f7329fbabdb7d921cdc246..2914c86577e9bb36e117be6910476020072e9027 100644 --- a/Packets/ParseArray.hh +++ b/Packets/ParseArray.hh @@ -23,6 +23,25 @@ #ifndef HH_ParseArray_ #define HH_ParseArray_ 1 +/** \defgroup parsecollection Collection parsers + + Collection parsers are parsers which build collections from other parsers. Examples are a vector + of 16bit unsigned integers or a list of lists of 32bit numbers and so on. + + Collection parsers provide a (reduced) STL sequence like interface. It depends on the type of + collection parser, what kind of sequence is modelled (e.g. random access sequence, forward + sequence etc). Most collections will also provide a kind of container wrapper to allow extensive + manipulations of the collection contents. A container wrapper is initialized with the collection + parser and then provides a more complete sequence interface. + + \important Parser lifetime has to be tightly checked when working with collection parsers since + \e every change of the collections size will invalidate \e all parsers and iterators referencing + the \e complete packet chain. Collection wrappers do \e not invalidate if the change is \e after + the collection. + + \ingroup packetparser +*/ + // Custom includes #include "PacketParser.hh" @@ -33,7 +52,16 @@ namespace senf { namespace detail { template <class> class Parse_Array_iterator; } - /* Parse_Array has the external interface of a container class + /** \brief Fixed size collection of fixed size elements + + Parse_Array will parse a sequence of <em>fixed size</em> parsers. The number of array + elements is given by the \e elements template parameter and is fixed at compile time. + + Each element will be parsed by \a ElementParser, which can be any <em>fixed size</em> + parser. The array models an STL random-access sequence with the restriction that elements + cannot be added or removed since the size is fixed. + + \ingroup parsecollection */ template <unsigned elements, class ElementParser> struct Parse_Array : public PacketParserBase diff --git a/Packets/ParseArray.ih b/Packets/ParseArray.ih index 9aa344b4696a644a49a799aba27cb8d0af1a315f..c5db831b7053d97f5537de685c0cb2311a86e5d5 100644 --- a/Packets/ParseArray.ih +++ b/Packets/ParseArray.ih @@ -28,6 +28,13 @@ ///////////////////////////////ih.p//////////////////////////////////////// +/** \brief Internal: Array and Vector iterator + + \internal + + This is the iterator type used for both Parse_Array and Parse_Vector. It is a model of random + access iterator. + */ template <class ElementParser> class senf::detail::Parse_Array_iterator : public boost::iterator_facade< Parse_Array_iterator<ElementParser>, @@ -43,7 +50,9 @@ public: // Needed to elide the []-proxy of iterator_facade ElementParser operator[](int i) const; - PacketParserBase::data_iterator raw() const; + PacketParserBase::data_iterator raw() const; ///< Return data_iterator + /**< Returns the raw data_iterator pointing to the beginning + of the current element */ protected: diff --git a/Packets/ParseInt.hh b/Packets/ParseInt.hh index 865fd562037909c00df5860fb6f5ee37192300cc..a54a056195eae71d32c07f850ea54ea62193cd12 100644 --- a/Packets/ParseInt.hh +++ b/Packets/ParseInt.hh @@ -36,6 +36,37 @@ namespace senf { + /** \defgroup parseint Integer parsers + + Most packet fields will ultimately contain some type of integral number. The integer parsers + allow to parse arbitrary integers in network byte order from 1-32 bit, both signed and + unsigned. There are two types of integer parsers: + + \li The normal integer parsers with interpret 1-4 byte integers (9, 16, 24, 32 bits) aligned + at byte boundaries. + \li The bitfield parsers which parse integers with 1-32 bits aligned at any bit. A special + case is the single bit flag parser. + + All fields are parsed in network byte order, the return value of all these parsers is the + value in host byte order. + + The interface of all these parsers is the same (p is an arbitrary integer parser instance, v + is an integer constant): + + \li <tt>p = v</tt>: Assigns the value to the packet field. + \li <tt>p.value(v)</tt>: same as above. + \li <tt>p.value()</tt>: Returns the fields value as an integer number. + \li Use of p like an integer in most contexts: <tt>p += v</tt>, <tt>p *= v</tt>, <tt>v = p + + 1</tt> and so on. You will only need to use the explicit \c value() member in rare + circumstances when the automatic conversion is ambiguous or in some template contexts. + + \ingroup packetparser + */ + + /** \brief Parse 8bit signed byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_Int8 : public detail::packet::ParseIntOps<Parse_Int8,boost::int8_t>, public PacketParserBase @@ -51,9 +82,16 @@ namespace senf { void value(value_type v) { i()[0] = v; } Parse_Int8 const & operator= (value_type other) { value(other); return *this; } }; + /** \brief Write parsed value to stream + \related Parse_Int8 + */ inline std::ostream & operator<<(std::ostream & os, Parse_Int8 const & i) { os << i.value(); return os; } + /** \brief Parse 8bit unsigned byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_UInt8 : public detail::packet::ParseIntOps<Parse_UInt8,boost::uint8_t>, public PacketParserBase @@ -69,9 +107,16 @@ namespace senf { void value(value_type v) { i()[0] = v; } Parse_UInt8 const & operator= (value_type other) { value(other); return *this; } }; + /** \brief Write parsed value to stream + \related Parse_UInt8 + */ inline std::ostream & operator<<(std::ostream & os, Parse_UInt8 const & i) { os << i.value(); return os; } + /** \brief Parse 16bit signed byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_Int16 : public detail::packet::ParseIntOps<Parse_Int16,boost::int16_t>, public PacketParserBase @@ -87,9 +132,16 @@ namespace senf { void value(value_type v) { detail::packet::write_uint16(i(),v); } Parse_Int16 const & operator= (value_type other) { value(other); return *this; } }; + /** \brief Write parsed value to stream + \related Parse_Int16 + */ inline std::ostream & operator<<(std::ostream & os, Parse_Int16 const & i) { os << i.value(); return os; } + /** \brief Parse 16bit unsigned byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_UInt16 : public detail::packet::ParseIntOps<Parse_UInt16,boost::uint16_t>, public PacketParserBase @@ -105,9 +157,16 @@ namespace senf { void value(value_type v) { detail::packet::write_uint16(i(),v); } Parse_UInt16 const & operator= (value_type other) { value(other); return *this; } }; + /** \brief Write parsed value to stream + \related Parse_UInt16 + */ inline std::ostream & operator<<(std::ostream & os, Parse_UInt16 const & i) { os << i.value(); return os; } + /** \brief Parse 24bit signed byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_Int24 : public detail::packet::ParseIntOps<Parse_Int24,boost::int32_t>, public PacketParserBase @@ -124,9 +183,16 @@ namespace senf { void value(value_type v) { detail::packet::write_uint24(i(),v); } Parse_Int24 const & operator= (value_type other) { value(other); return *this; } }; + /** \brief Write parsed value to stream + \related Parse_Int24 + */ inline std::ostream & operator<<(std::ostream & os, Parse_Int24 const & i) { os << i.value(); return os; } + /** \brief Parse 24bit unsigned byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_UInt24 : public detail::packet::ParseIntOps<Parse_UInt24,boost::uint32_t>, public PacketParserBase @@ -142,9 +208,16 @@ namespace senf { void value(value_type v) { detail::packet::write_uint24(i(),v); } Parse_UInt24 const & operator= (value_type other) { value(other); return *this; } }; + /** \brief Write parsed value to stream + \related Parse_UInt24 + */ inline std::ostream & operator<<(std::ostream & os, Parse_UInt24 const & i) { os << i.value(); return os; } + /** \brief Parse 32bit signed byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_Int32 : public detail::packet::ParseIntOps<Parse_Int32,boost::int32_t>, public PacketParserBase @@ -160,9 +233,16 @@ namespace senf { void value(value_type v) { detail::packet::write_uint32(i(),v); } Parse_Int32 const & operator= (value_type other) { value(other); return *this; } }; + /** \brief Write parsed value to stream + \related Parse_Int32 + */ inline std::ostream & operator<<(std::ostream & os, Parse_Int32 const & i) { os << i.value(); return os; } + /** \brief Parse 32bit unsigned byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_UInt32 : public detail::packet::ParseIntOps<Parse_UInt32,boost::uint32_t>, public PacketParserBase @@ -178,9 +258,34 @@ namespace senf { void value(value_type v) { detail::packet::write_uint32(i(),v); } Parse_UInt32 const & operator= (value_type other) { value(other); return *this; } }; + /** \brief Write parsed value to stream + \related Parse_UInt32 + */ inline std::ostream & operator<<(std::ostream & os, Parse_UInt32 const & i) { os << i.value(); return os; } + /** \brief Parse signed bitfield with up to 32bit's + + This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a + End. Bits are numbered <em>most significant bit first</em> as this is the customary + numbering used when defining packet data structures. \a Start and \a End can be \e + arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c + Parse_IntField<53,81> is a valid 30 bit field. + + When defining a compound parser with several bit fields, you need to take care of the fact, + that several integer field parsers will interpret the same data \e bytes (but not the same + \e bits). It is customary for several integer field parsers to start at the same byte offset + with ever increasing bit offsets. + + \see parseint + + \implementation The integer field parser is highly optimized. Since the bit positions are + compile-time constants, the compiler will create optimized bit-masks to directly access + the value. The parser is also optimized to access the minimum number of data bytes + necessary. + + \ingroup parseint + */ template <unsigned Start, unsigned End> struct Parse_IntField : public detail::packet::ParseIntOps<Parse_IntField<Start,End>,boost::int32_t>, @@ -205,10 +310,35 @@ namespace senf { BOOST_STATIC_ASSERT( Start<End ); BOOST_STATIC_ASSERT( End-Start<=32 ); }; + /** \brief Write parsed value to stream + \related Parse_IntField + */ template <unsigned Start, unsigned End> inline std::ostream & operator<<(std::ostream & os, Parse_IntField<Start,End> const & i) { os << i.value(); return os; } + /** \brief Parse unsigned bitfield with up to 32bit's + + This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a + End. Bits are numbered <em>most significant bit first</em> as this is the customary + numbering used when defining packet data structures. \a Start and \a End can be \e + arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c + Parse_IntField<53,81> is a valid 30 bit field. + + When defining a compound parser with several bit fields, you need to take care of the fact, + that several integer field parsers will interpret the same data \e bytes (but not the same + \e bits). It is customary for several integer field parsers to start at the same byte offset + with ever increasing bit offsets. + + \see parseint + + \implementation The integer field parser is highly optimized. Since the bit positions are + compile-time constants, the compiler will create optimized bit-masks to directly access + the value. The parser is also optimized to access the minimum number of data bytes + necessary. + + \ingroup parseint + */ template <unsigned Start, unsigned End> struct Parse_UIntField : public detail::packet::ParseIntOps<Parse_UIntField<Start,End>,boost::uint32_t>, @@ -229,13 +359,30 @@ namespace senf { BOOST_STATIC_ASSERT( Start<End ); BOOST_STATIC_ASSERT( End-Start<=32 ); }; + /** \brief Write parsed value to stream + \related Parse_UIntField + */ template <unsigned Start, unsigned End> inline std::ostream & operator<<(std::ostream & os, Parse_UIntField<Start,End> const & i) { os << i.value(); return os; } - template <unsigned bit> + /** \brief Parse single-bit flag + + This parser will parse a single bit as True/False value. Bits are numbered <em>most + significant bit first</em> as this is the customary numbering used when defining packet data + structures. \a Bit can be arbitrary, \c Parse_Flag<75> is a valid flag parser. + + When defining a compound parser with several bit fields, you need to take care of the fact, + that several integer field parsers will interpret the same data \e bytes (but not the same + \e bits). It is customary for several integer field parsers to start at the same byte offset + with ever increasing bit offsets. + + \see parseint + \ingroup parseint + */ + template <unsigned Bit> struct Parse_Flag - : public detail::packet::ParseIntOps<Parse_Flag<bit>,bool>, + : public detail::packet::ParseIntOps<Parse_Flag<Bit>,bool>, public PacketParserBase { Parse_Flag(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} @@ -243,17 +390,20 @@ namespace senf { /////////////////////////////////////////////////////////////////////////// typedef bool value_type; - static size_type const fixed_bytes = bit/8+1; + static size_type const fixed_bytes = Bit/8+1; - value_type value() const { return i()[bit/8] & (1<<(7-(bit%8))); } + value_type value() const { return i()[Bit/8] & (1<<(7-(Bit%8))); } void value(value_type v) { - if (v) i()[0] |= 1<<(7-(bit%8)); - else i()[0] &= ~(1<<(7-(bit%8))); + if (v) i()[0] |= 1<<(7-(Bit%8)); + else i()[0] &= ~(1<<(7-(Bit%8))); } Parse_Flag const & operator= (value_type other) { value(other); return *this; } }; - template <unsigned bit> - inline std::ostream & operator<<(std::ostream & os, Parse_Flag<bit> const & i) + /** \brief Write parsed value to stream + \related Parse_Flag + */ + template <unsigned Bit> + inline std::ostream & operator<<(std::ostream & os, Parse_Flag<Bit> const & i) { os << i.value(); return os; } } diff --git a/Socket/ClientSocketHandle.ih b/Socket/ClientSocketHandle.ih index 6ee58369db3bc3eed6e2aacb486f0a113ea39823..6000c5d3b83323d7f7d98b72446fb4749398cdba 100644 --- a/Socket/ClientSocketHandle.ih +++ b/Socket/ClientSocketHandle.ih @@ -35,6 +35,13 @@ namespace detail { /////////////////////////////////////////////////////////////////////// // senf::detail::ReadRange + /** \brief Internal: Choose optimal read implementation + + \internal + + If the range iterator is a contiguous_storage_iterator, the data is *directly* read into the + range, otherwise a temporary storage area is used. + */ template <class Handle, class ForwardWritableRange, bool IsContiguous> struct ReadRange { @@ -45,6 +52,8 @@ namespace detail { readfrom(Handle & handle, ForwardWritableRange & range, typename Handle::Address & addr); }; +# ifndef DOXYGEN + template <class Handle, class ForwardWritableRange> struct ReadRange<Handle, ForwardWritableRange, true> { @@ -55,9 +64,18 @@ namespace detail { readfrom(Handle & handle, ForwardWritableRange & range, typename Handle::Address & addr); }; +# endif + /////////////////////////////////////////////////////////////////////// // senf::detail::WriteRange + /** \brief Internal: Choose optimal write implementation + + \internal + + If the range iterator is a contiguous_storage_iterator, the data is *directly* written from + the range, otherwise a temporary storage area is used. + */ template <class Handle, class ForwardReadableRange, bool IsContiguous> struct WriteRange { @@ -69,6 +87,8 @@ namespace detail { typename Handle::Address const & addr); }; +# ifndef DOXYGEN + template <class Handle, class ForwardReadableRange> struct WriteRange<Handle, ForwardReadableRange, true> { @@ -80,6 +100,8 @@ namespace detail { typename Handle::Address const & addr); }; +# endif + }} ///////////////////////////////ih.e//////////////////////////////////////// diff --git a/doclib/html-munge.xsl b/doclib/html-munge.xsl index 69136e0e4eb0eecbd4b02023aa0a9a3c4bee0874..6bc703841436277320974b35fbd9df60b08c0d6c 100644 --- a/doclib/html-munge.xsl +++ b/doclib/html-munge.xsl @@ -121,7 +121,7 @@ </xsl:call-template> </xsl:template> - <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Definition at line ')]"> + <xsl:template match="p[starts-with(text(),'Definition at line ')]"> <xsl:call-template name="add-class"> <xsl:with-param name="class">sourceline</xsl:with-param> </xsl:call-template> @@ -150,6 +150,16 @@ <xsl:with-param name="class">reimplementedin</xsl:with-param> </xsl:call-template> </xsl:template> + + <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Implemented in ')]"> + <xsl:call-template name="add-class"> + <xsl:with-param name="class">implementedin</xsl:with-param> + </xsl:call-template> + </xsl:template> + + <!-- Remove external items from the namespace index --> + <xsl:template match="div[@id='content2']/table[contains(preceding-sibling::h1/text(),'Namespace Reference')]/tr[td[@class='memItemRight']/a[1][@class='elRef'][@doxygen]]"> + </xsl:template> <!-- Remove [external] references from the modules page --> <xsl:template match="div[@id='content2']/ul/li[a/@class='elRef'][a/@doxygen][code/text()='[external]'][not(ul)]"> diff --git a/doclib/senf.css b/doclib/senf.css index e6e9575cb72a5113d3362a0f8dd79387d0cd3100..476f44f9e7514c16eac52753cb730181804dc5e1 100644 --- a/doclib/senf.css +++ b/doclib/senf.css @@ -322,15 +322,19 @@ p.memtitle { color: #1a41a8; font-weight: bold; margin-right: 14px; - border-bottom: 1px solid #84b0c7; } -p.sourceline, p.references, p.referencedby, p.reimplementedfrom, p.reimplementedin { +p.sourceline, p.references, p.referencedby, p.reimplementedfrom, p.reimplementedin, +p.implementedin { color: #666666; font-size: 75%; - margin-left: 10em; margin-bottom: .2em; margin-top: .2em; +} + +div.memdoc p.sourceline, p.references, p.referencedby, p.reimplementedfrom, p.reimplementedin, +p.implementedin { + margin-left: 10em; text-indent: -4em; } diff --git a/senf.dict b/senf.dict index 2ad10dad2db3a1a27420aea1b5ea6601972347ba..e0e04c4ab88d7b253e740efcbeca592c77799643 100644 --- a/senf.dict +++ b/senf.dict @@ -3,11 +3,9 @@ addtogroup berlios bitfield bund -Bund callbacks cerr cfi -CFI ConcretePacket const createAfter @@ -18,6 +16,7 @@ DefaultBundle defaultInit defgroup dil +ElementParser endcode eth ethernet @@ -25,15 +24,12 @@ EthernetPacket EthernetPacketType EthernetParser ethertype -Ethertype EthVLan findNext findPrev fokus -FOKUS FooParser fraunhofer -Fraunhofer fuer hh hideinitializer @@ -47,11 +43,11 @@ init initHeadSize initSize Institut +Int +IntField InvalidPacketChainException ip -IP IpV -IPv4 key Kommunikationssysteme Kompetenzzentrum @@ -59,7 +55,6 @@ li MACAddress mainpage mixin -Mixin namespace NextPacket nextPacketKey @@ -91,8 +86,11 @@ PacketType PacketTypeBase PacketTypeMixin PacketTypeNotRegistered -PacketType's param +ParseArray +parsecollection +parseint +ParseInt parseNextAs png prev @@ -107,7 +105,6 @@ rerference SatCom Satelitenkommunikation senf -SENF SimplePacketType SimpleVectorSizer someField @@ -124,14 +121,12 @@ stefan STL struct structors -Structors templated TruncatedPacketException tt ttl typeField udp -UDP UDPPacket UInt UIntField diff --git a/senfscons/SENFSCons.py b/senfscons/SENFSCons.py index de0dbb6bf1536bfa8de0b24d44aea6e32c7d9952..ef647d1212d350b975b39d2295c80342622b610a 100644 --- a/senfscons/SENFSCons.py +++ b/senfscons/SENFSCons.py @@ -389,7 +389,7 @@ def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []): SCons.Action.Action(("for html in %s/*.html; do " + " echo $$html;" + " sed -e 's/id=\"current\"/class=\"current\"/' $${html}" + - " | tidy -ascii -q --show-warnings no --fix-uri no" + + " | tidy -ascii -q --show-warnings no --fix-uri no " + " | xsltproc --nonet --html --stringparam topdir %s -o $${html}.new %s - 2>&1" + " | grep '^-'" + " | grep -v 'ID .* already defined';" +