X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FListParser.hh;h=8807578ed0217016cb1450891e082a42b5dcea05;hb=fd3a0e8ac95d1158e9ea661ddf9187b67c70169f;hp=c101b82bc31b1c9e5ec541b11af227413fa8d7db;hpb=8f1a688cea76f2e76bfa0193dff9c1538929147e;p=senf.git diff --git a/Packets/ListParser.hh b/Packets/ListParser.hh index c101b82..8807578 100644 --- a/Packets/ListParser.hh +++ b/Packets/ListParser.hh @@ -23,8 +23,8 @@ /** \file \brief ListParser public header */ -#ifndef HH_ListParser_ -#define HH_ListParser_ 1 +#ifndef HH_SENF_Packets_ListParser_ +#define HH_SENF_Packets_ListParser_ 1 // Custom includes #include @@ -50,12 +50,24 @@ namespace senf { provides a reduced interface to this sequence, the container wrapper provides the complete interface. - Pare_List makes use of a policy template argument, \a ListPolicy, to customize the way the - list is laid out. This policy is given quite some freedom in the list - implementation. It is however important, that list elements always follow each other - without padding (if padding is needed, it needs to be part of the element parser). + ListParser makes use of a policy template argument, \a ListPolicy, to customize the way the + list is laid out. This policy is given quite some freedom in the list implementation. It is + however important, that list elements always follow each other without padding (if + padding is needed, it needs to be part of the element parser). + + You will normally not instantiate ListParser directly, you will use the \ref + SENF_PARSER_LIST() helper macro. + + Some basic list access methods are defined as parser members. To access the complete list + API however you will need to instantiate a container wrapper for the list. See \ref + packet_usage_fields_collection. + + \see + \ref How to access \ref packet_usage_fields_collection + SENF_PARSER_LIST() macro used to define list fields \n + ListParser_Container list container wrapper API \n + ExampleListPolicy - \see ExampleListPolicy \ingroup parsecollection */ template @@ -217,18 +229,101 @@ namespace senf { size_type i_; }; -# define SENF_PARSER_LIST(name, size, elt_type) \ - SENF_PARSER_LIST_I(public, name, size, elt_type) + /** \brief Define ListParser field + + This macro is a special helper to define a senf::ListParser type field, a list of elements + of type \a elt_type (a parser) which size is determined by \a size. + + \code + // The size field should be declared private or read-only (size is accessible via the list) + SENF_PARSER_PRIVATE_FIELD ( list_size_, senf::UInt16Parser ); + // Define the list + SENF_PARSER_LIST ( list, list_size_, EltParser ); + \endcode + + Here \c EltParser can be an arbitrary parser and need not have a fixed size. + + \warning Realize, that the \a size field is controlled by the list parser. This field + should therefore be declared either read-only or private and must be changed only via + the list parser. + + Further additional tags are supported which modify the type of list created: + + + + + + + + + +
\c bytes(\a size)\a size gives the size of the list in bytes not the + number of contained elements
\c packetSize()Use the size of the packet to get the list size. The + list will occupy all space up to the end of the packet.
\c transform(\a transform, \a size)The \a transform is applied to the \a + size value, the value is not used directly
\c transform(\a transform, \c bytes(\a size))The \a transform is applied to + the \a size value. The value is then interpreted containing the list size in bytes not + number of elements
+ + The optional \a transform is a class with the following layout + \code + struct MyTransform + { + typedef ... value_type; + static value_type get(other_type v); + static other_type set(value_type v); + }; + \endcode + + \c other_type is \a size ::\c value_type, the type of the value returned by the \a size + field, whereas the \c value_type typedef is the arbitrary return type of the transform. + + The tags are applied to the \a size parameter: + \code + SENF_PARSER_LIST ( list, transform(MyTransform, list_size_), EltParser ); + \endcode + + \warning There are some caveats when working with \c bytes() type lists: + \li You may only change the size of a contained element from a container wrapper. + \li While you hold a container wrapper, only access the packet through this wrapper + or a nested wrapper either for reading or writing. + + \warning If lists are nested, you need to allocate a container wrapper for each level and + may only access the packet through the lowest-level active container wrapper. + + \implementation These restrictions are necessary to ensure correct recalculation of the + bytes field. For more info, see the comments in \ref ListBParser.ih + + \param[in] name field name + \param[in] size name of field giving the list size + \param[in] elt_type list element type + + \see + How to use \ref packet_usage_fields_collection \n + senf::ListParser the list parser API for list field access + senf::ListParser_Container the list parser container API for list field access + + \hideinitializer + \ingroup packetparsermacros + */ +# define SENF_PARSER_LIST(name, size, elt_type) \ + SENF_PARSER_LIST_I(public, name, size, elt_type) + + /** \brief Define private ListParser field + + \see \ref SENF_PARSER_LIST() -# define SENF_PARSER_PRIVATE_LIST(name, size, elt_type) \ + \hideinitializer + \ingroup packetparsermacros + */ +# define SENF_PARSER_PRIVATE_LIST(name, size, elt_type) \ SENF_PARSER_LIST_I(private, name, size, elt_type) } ///////////////////////////////hh.e//////////////////////////////////////// #endif -#if !defined(HH_Packets__decls_) && !defined(HH_ListParser_i_) -#define HH_ListParser_i_ +#if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_ListParser_i_) +#define HH_SENF_Packets_ListParser_i_ //#include "ListParser.cci" #include "ListParser.ct" #include "ListParser.cti"