X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FPacketParser.hh;h=8c218e06bb347e236034e959d69eaff8675a2ffd;hb=c45c112ae88196ea8da9c5a9efb0e167196744d2;hp=a00da0d86cdd10dcd423e8f76bcb63b1231cd910;hpb=f73fa16ed5abdce272ac77f8b8b9ef2b9922c266;p=senf.git diff --git a/Packets/PacketParser.hh b/Packets/PacketParser.hh index a00da0d..8c218e0 100644 --- a/Packets/PacketParser.hh +++ b/Packets/PacketParser.hh @@ -1,8 +1,8 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institute for Open Communication Systems (FOKUS) -// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -136,22 +136,22 @@ parsers). When defining composite parsers without the help of the \ref packetparsermacros, you should provide those same members. - \subsection parserimpl_packet Packet parsers + \subsection parserimpl_packet Protocol parsers - Packet parsers are composite parsers with relaxed requirements. Since a packet parser will never - be used as a sub-parser (it will not be used within another composite parser or as value type in - a collection parser), the value returned by senf::bytes for this parser must not necessarily - cover the complete packet (e.g. if the packet has a trailer, the trailer will live outside the - range given by senf::bytes). You may define any member you want to have in your packets field - interface. These members may access the packet data in any way. You just need to ensure, that - the integration into the packet-type is correct (the senf::PacketTypeMixin will by default use - senf::bytes() to find the end of the header). + Protocol parsers are composite parsers with relaxed requirements. Since a Protocol parser will + never be used as a sub-parser (it will not be used within another composite parser or as value + type in a collection parser), the value returned by senf::bytes for this parser must not + necessarily cover the complete packet (e.g. if the packet has a trailer, the trailer will live + outside the range given by senf::bytes). You may define any member you want to have in your + packets field interface. These members may access the packet data in any way. You just need to + ensure, that the integration into the packet-type is correct (the senf::PacketTypeMixin will by + default use senf::bytes() to find the end of the header).
*/ -#ifndef HH_PacketParser_ -#define HH_PacketParser_ 1 +#ifndef HH_SENF_Packets_PacketParser_ +#define HH_SENF_Packets_PacketParser_ 1 // Custom includes #include @@ -264,10 +264,23 @@ namespace senf { here. The size of the interpreted is given by senf::bytes(parser instance). */ + + data_iterator i(size_type offset) const; ///< Return iterator \a offset bytes from the start + /**< The return value is the same as i() + \a + offset. However, the parser checks, that the iterator is + still within range of the raw data + container. Otherwise a TruncatedPacketException is + thrown. + + \throws TruncatedPacketException if the raw data + container does not hold at least \a offset bytes + starting at i(). */ + state_type state() const; ///< Return state of this parser /**< The value returned should be interpreted as an opaque value provided just to be forwarded to other parsers. */ + PacketData & data() const; ///< Access the packets raw data container /**< This member will return the raw data container holding the data which is parsed by \c this parser. */ @@ -282,6 +295,7 @@ namespace senf { /**< This is the constructor used by most parsers. The parameters are just forwarded from the derived classes constructor parameters. */ + PacketParserBase(data_iterator i, state_type s, size_type size); ///< Size checking constructor /**< In addition to the standard constructor, this @@ -303,6 +317,7 @@ namespace senf { bool check(size_type size) const; ///< Check size of data container /**< \returns \c true, if the data container holds at least \a size beginning at i(), \c false otherwise. */ + void validate(size_type size) const; ///< Validate size of data container /**< \throws TruncatedPacketException if the raw data container does not hold at least \a size bytes @@ -312,18 +327,30 @@ namespace senf { /**< Creates a new instance of \a Parser to parse data beginning at \a i. Automatically passes \a state() to the new parser. */ + + template Parser parse(Arg const & arg, data_iterator i) const; + ///< Create sub-parser + /**< This is like parse(data_iterator), however it passes + the extra argument \a arg to the \a Parser + constructor. */ + template Parser parse(size_type n) const; ///< Create sub-parser /**< Creates a new instance of \a Parser to parse data * beginning at i() + \a n. Automatically passes \a state() to the new parser. */ + template Parser parse(Arg const & arg, size_type n) const; + ///< Create sub-parser + /**< This is like parse(size_type), however it passes the + extra argument \a arg to the \a Parser constructor. */ + void defaultInit() const; ///< Default implementation /**< This is just an empty default implementation. Re-implement this member in your own parsers if needed. */ Packet packet() const; ///< Get packet this parser is parsing from - /**< \important This member should only be used from packet + /**< \note This member should only be used from packet parsers when access to previous or following packets is needed e.g. for calculating checksums etc. */ @@ -354,6 +381,7 @@ namespace senf { PacketParserBase::size_type bytes(Parser p); namespace detail { template class ParserInitBytes; } + namespace detail { template class ParserIsFixed; } /** \brief Return number of bytes to allocate to new object of given type @@ -374,6 +402,24 @@ namespace senf { struct init_bytes : public detail::ParserInitBytes {}; + /** \brief Test, whether a parser is a fixed-size parser + + This meta-function is called like + \code + senf::is_fixed::value + \endcode + + This expression evaluates to a compile-time constant boolean expression which is \c true, if + \a SomeParser is a fixed size parser, \c false otherwise + + \param[in] Parser The Parser to test + \returns \c true, if \a Parser is fixed size, \c false otherwise + \ingroup packetparser + */ + template + struct is_fixed : public detail::ParserIsFixed + {}; + # ifndef DOXYGEN template typename boost::enable_if< @@ -449,69 +495,12 @@ namespace senf { SENF_PARSER_FINALIZE(VoidPacketParser); }; - /** \brief Iterator re-validating Parser wrapper - - An ordinary parser will be invalidated whenever the raw data container's size is - changed. This can complicate some algorithms considerably. - - This wrapper will update the parsers iterator (the value returned by the i() member) on - every access. This ensures that the iterator will stay valid. - - \attention Beware however, if you insert or remove data before the safe wrapper, the - location will \e not be updated accordingly and therefore the parser will be - invalid. - - Additionally a SafePacketParserWrapper has an uninitialized state. The only allowed operations in - this state are the boolean test for validity and assigning another parser. - - \ingroup packetparser - */ - template - class SafePacketParserWrapper - : public safe_bool< SafePacketParserWrapper > - { - public: - /////////////////////////////////////////////////////////////////////////// - // Types - - /////////////////////////////////////////////////////////////////////////// - ///\name Structors and default members - ///@{ - - // default copy constructor - // default copy assignment - // default destructor - SafePacketParserWrapper(); ///< Create an empty uninitialized SafePacketParserWrapper - - // conversion constructors - SafePacketParserWrapper(Parser parser); ///< Initialize SafePacketParserWrapper from \a parser - - SafePacketParserWrapper & operator=(Parser parser); ///< Assign \a parser to \c this - - ///@} - /////////////////////////////////////////////////////////////////////////// - - Parser operator*() const; ///< Access the stored parser - /**< On every access, the stored parsers iterator will be - updated / re-validated. */ - Parser const * operator->() const; ///< Access the stored parser - /**< On every access, the stored parsers iterator will be - updated / re-validated. */ - bool boolean_test() const; ///< Check validity - - protected: - - private: - mutable boost::optional parser_; - senf::safe_data_iterator i_; - }; - } ///////////////////////////////hh.e//////////////////////////////////////// #endif -#if !defined(HH_Packets__decls_) && !defined(HH_PacketParser_i_) -#define HH_PacketParser_i_ +#if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketParser_i_) +#define HH_SENF_Packets_PacketParser_i_ #include "PacketParser.cci" #include "PacketParser.ct" #include "PacketParser.cti"