X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FParseVec.hh;h=11546710d490e5d31e50e1f3bcae910564581a86;hb=81ffa1c459b96dd44472bcef37e1e373934ee138;hp=2d2b0b5bb2c7064140388e235334c484b9a07144;hpb=31d85cd6b8e03c5ecc924ca8892906be1bab702f;p=senf.git diff --git a/Packets/ParseVec.hh b/Packets/ParseVec.hh index 2d2b0b5..1154671 100644 --- a/Packets/ParseVec.hh +++ b/Packets/ParseVec.hh @@ -20,14 +20,18 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +/** \file + \brief ParseVec public header */ + #ifndef HH_ParseVec_ #define HH_ParseVec_ 1 // Custom includes -#include // for std::pair #include -#include // for boost::noncopyable -#include "ParserBase.hh" +#include +#include +#include +#include "PacketParser.hh" #include "ParseArray.hh" // for Parse_Array_iterator //#include "ParseVec.mpp" @@ -35,92 +39,207 @@ namespace senf { - - template class Parse_Vector_wrapper; - - template - struct Parse_Vector : public ParserBase + template class Parse_Vector_Container; + + /** \brief Collection of fixed-size elements + + A Vector is a collection of fixed-size elements of which the size of the collection can be + determined directly (that is without traversing the collection). This allows very efficient + random access to the elements of the collection. + + A vector is a model of an STL random-access sequence. The parser only provides a reduced + interface, the container wrapper however completes this interface. + + Parse_Vector makes use of a policy template argument, \a Sizer, to customize the way the + containers size is obtained. You will normally not instantiate Parser_Vector directly, you + will use one of the 'template typedefs' (which are templated structures since C++ does not + provide real template typedefs) provided with the policy implementations. + + \todo Make the sizer a private base-class to profit from the empty-base-class optimization + + \see ExampleVectorPolicy + \ingroup parsecollection + */ + template + struct Parse_Vector : public PacketParserBase { - typedef typename SizeParser::template rebind::parser size_parser; - - /////////////////////////////////////////////////////////////////////////// - // Parser interface - - template - struct rebind { typedef Parse_Vector parser; }; - typedef Iterator byte_iterator; + Parse_Vector(data_iterator i, state_type s); + Parse_Vector(Sizer sizer, data_iterator i, state_type s); + ///< Additional sizer specific constructor + /**< This constructor may be used, if the sizer needs + additional parameters. */ - explicit Parse_Vector(SizeParser const & size); - Parse_Vector(size_parser const & size, Iterator const & i); - - unsigned bytes() const; - void check(Iterator const & e) const; + size_type bytes() const; void init() const; + static const size_type init_bytes = Sizer::init_bytes; + /////////////////////////////////////////////////////////////////////////// // Container interface - typedef typename Parser::template rebind::parser value_type; - typedef impl::Parse_Array_iterator iterator; - typedef unsigned size_type; - typedef int difference_type; - typedef std::pair range_type; - - template - struct wrapper { typedef Parse_Vector_wrapper t; }; + typedef ElementParser value_type; + typedef detail::Parse_Array_iterator iterator; + typedef iterator const_iterator; + typedef Parse_Vector_Container container; 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; + value_type front() const; + value_type back() const; + + // Mutators + + // The mutators provided here are those which don't take an iterator argument. + // If you need to pass an iterator it is much simpler and cleaner to use the + // 'container' wrapper + + template void push_back (Value value, size_type n=1) const; + void push_back_space (size_type n=1) const; + template void push_front (Value value, size_type n=1) const; + void push_front_space (size_type n=1) const; + void resize (size_type n) const; + template void resize (size_type n, Value value) const; private: - size_parser size_; + Sizer sizer_; + + friend class Parse_Vector_Container; + }; - template friend class Parse_Vector_wrapper; + namespace detail { template class Parse_VectorN_Sizer; } + + /** \brief Vector with prefix sizing + + This is a 'template typedef'. It defines a vector with a directly preceding size + field holding the number of vector elements. The size field is considered part of the + vector. + \code + // Define MyVector as a vector of 16bit unsigned elements with a directly preceding + // 8bit unsigned size field + typedef senf::Parse_VectorN::parser MyVector; + \endcode + + \param ElementParser \e fixed-size parser for parsing the vector elements + \param SizeParser parser for parsing the vector size (number of elements) + + \see Parse_Vector + \ingroup parsecollection + */ + template + struct Parse_VectorN + { + typedef Parse_Vector< ElementParser, + detail::Parse_VectorN_Sizer > parser; + }; + + /** \brief Example vector sizer. ONLY FOR EXPOSITION + + This class shows the interface which must be implemented by a vector sizer policy. It is not + a vector sizer, it is only a declaration of the interface: + \code + struct ExampleVectorPolicy + { + // optional typedefs used to simplify all other declarations + typedef PacketParserBase::size_type size_type; + typedef PacketParserBase::data_iterator iterator; + typedef PacketParserBase::state_type state_type; + + // mandatory members + static const size_type init_bytes = 0; + size_type size (iterator i, state_type s) const; + void size (iterator i, state_type s, size_type v) const; + iterator begin (iterator i, state_type s) const; + size_type bytes (iterator i, state_type s) const; + void init (iterator i, state_type s) const; + }; + \endcode + + A sizer may if needed define additional data members. + */ + struct ExampleVectorPolicy + { + typedef PacketParserBase::size_type size_type; + typedef PacketParserBase::data_iterator iterator; + typedef PacketParserBase::state_type state_type; + + static const size_type init_bytes = 0; ///< Size of a new vector of this size + /**< Initial size which needs to be allocated to this type + of list */ + + size_type size (iterator i, state_type s) const; ///< Get current vector size + /**< Return the current number of elements in the + vector. */ + void size (iterator i, state_type s, size_type v) const; ///< Change vector size + /**< Set the size of the vector to \a v. */ + iterator begin (iterator i, state_type s) const; + ///< Return data_iterator to first element + /**< The returned data_iterator must point to the beginning + of the first vector element. The last iterator can than + automatically be calculated from the fixed element size + and the number of vector elements. */ + size_type bytes (iterator i, state_type s) const; ///< Size of vector parser + /**< Return the size of the complete vector in bytes. This + is not necessarily the same as \c size() * \e + fixed_element_bytes. */ + void init (iterator i, state_type s) const; ///< Initialize new vector + /** Called to initialize a new vector after allocating + init_bytes number of bytes for the vector. */ }; - /** \brief + /** \brief Parse_Vector container wrapper - Holds a reference to the container ! + This is the container wrapper used for vector parsers. The container wrapper will stay valid + after changing the collection. However the container still depends on the packet and will be + invalidated if the Packet is deallocated or if the packet size is changed from without the + container wrapper (more precisely, it is invalided if the insertion/deletion happens before + the vector in the packet data). + + The vector container wrapper provides a complete STL random-access sequence interface. + + \code + SomePacket p (...); + SomePacket::aVectorCollection_t::container c (p->aVectorCollection()); + c.insert(c.begin(), ... ); + \endcode + + \see Parse_Vector */ - template - class Parse_Vector_wrapper - : public boost::noncopyable + template + class Parse_Vector_Container { 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 iterator; - typedef unsigned size_type; - typedef int difference_type; - typedef std::pair range_type; + typedef Parse_Vector parser_type; + typedef PacketParserBase::data_iterator data_iterator; + typedef PacketParserBase::size_type size_type; + typedef PacketParserBase::difference_type difference_type; + typedef ElementParser value_type; + typedef detail::Parse_Array_iterator iterator; + typedef iterator const_iterator; + typedef PacketParserBase::state_type state_type; /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members ///@{ - template - Parse_Vector_wrapper(Parse_Vector const & vector, Container & container); - // no default constructor - // no copy + // default copy // default destructor - // no conversion constructors + // conversion constructors + + Parse_Vector_Container(parser_type const & vector); ///@} /////////////////////////////////////////////////////////////////////////// - ///\name APacketRegistry.essors + + ///\name Accessors ///@{ size_type size() const; @@ -128,41 +247,71 @@ namespace senf { iterator begin() const; iterator end() const; - range_type range() const; value_type operator[](difference_type i) const; + value_type front() const; + value_type back() const; ///@} - /////////////////////////////////////////////////////////////////////////// ///\name Mutators ///@{ - void shift(iterator pos, size_type n=1); + iterator shift(iterator pos, size_type n=1); template void insert(iterator pos, Value const & t); template void insert(iterator pos, size_type n, Value const & t); - template - void insert(iterator pos, InputIterator f, InputIterator l); +# ifndef DOXYGEN + template + void insert(iterator pos, ForwardIterator f, ForwardIterator l, + typename boost::disable_if< boost::is_convertible >::type * = 0); +# else + template + void insert(iterator pos, ForwardIterator f, ForwardIterator l); +# endif void erase(iterator pos, size_type n=1); void erase(iterator f, iterator l); void clear(); + template void push_back (Value value, size_type n=1); + void push_back_space (size_type n=1); + template void push_front (Value value, size_type n=1); + void push_front_space (size_type n=1); + void resize (size_type n); + template void resize (size_type n, Value value); + + ///@} + + ///\name Parser interface + ///@{ + + parser_type parser() const; + data_iterator i() const; + state_type state() const; + PacketData & data() const; + + size_type bytes() const; + void init() const; + ///@} protected: private: + void setSize(size_type value); + Sizer sizer_; + state_type state_; size_type i_; - size_type size_i_; - Container & container_; }; } ///////////////////////////////hh.e//////////////////////////////////////// +#endif +#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseVec_i_) +#define HH_ParseVec_i_ //#include "ParseVec.cci" #include "ParseVec.ct" #include "ParseVec.cti" @@ -176,4 +325,5 @@ namespace senf { // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" +// comment-column: 40 // End: