From: g0dil Date: Tue, 16 Oct 2007 12:46:33 +0000 (+0000) Subject: Packets: Add additional parse helper macros X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=3f8c584bbd5848888437d31c37a43eeac60c98f4;p=senf.git Packets: Add additional parse helper macros Packets: Add parse helper unit-test git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@464 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/ParseHelpers.hh b/Packets/ParseHelpers.hh index 9fc6cc0..46bb7b5 100644 --- a/Packets/ParseHelpers.hh +++ b/Packets/ParseHelpers.hh @@ -157,8 +157,6 @@ #define SENF_PARSE_BITFIELD BOOST_PP_CAT( SENF_PARSE_BITFIELD_ , SENF_PARSER_TYPE ) #define SENF_PARSE_BITFIELD_RO BOOST_PP_CAT( SENF_PARSE_BITFIELD_RO_ , SENF_PARSER_TYPE ) -#define SENF_PARSER_FINALIZE BOOST_PP_CAT( SENF_PARSER_FINALIZE_ , SENF_PARSER_TYPE ) - #define SENF_PARSER_SKIP BOOST_PP_CAT( SENF_PARSER_SKIP_ , SENF_PARSER_TYPE ) #define SENF_PARSER_GOTO BOOST_PP_CAT( SENF_PARSER_GOTO_ , SENF_PARSER_TYPE ) #define SENF_PARSER_GOTO_OFFSET BOOST_PP_CAT( SENF_PARSER_GOTO_OFFSET_ , SENF_PARSER_TYPE ) @@ -166,6 +164,8 @@ #define SENF_PARSER_INIT() void init(int) +#define SENF_PARSER_FINALIZE BOOST_PP_CAT( SENF_PARSER_FINALIZE_ , SENF_PARSER_TYPE ) + ///////////////////////////////hh.e//////////////////////////////////////// #endif #if !defined(HH_Packets__decls_) && !defined(HH_ParseHelpers_i_) diff --git a/Packets/ParseHelpers.ih b/Packets/ParseHelpers.ih index 8b76054..4b381e1 100644 --- a/Packets/ParseHelpers.ih +++ b/Packets/ParseHelpers.ih @@ -63,9 +63,9 @@ SENF_MPL_SLOT_SET(index, 1); \ SENF_MPL_SLOT_SET(init_bytes, senf::init_bytes::value); \ size_type field_offset_(senf::mpl::rv<1>*) const { \ - return senf::bytes( *static_cast(this) ); \ + return senf::bytes( *static_cast(this) ); \ } \ - void init_chain(senf::mpl::rv*) { \ + void init_chain(senf::mpl::rv<1>*) { \ name::init(); \ } \ public: @@ -83,82 +83,76 @@ # /////////////////////////////////////////////////////////////////////////// # // SENF_PARSE_FIELD_* # -# define SENF_PARSE_FIELD_var(name, type) SENF_PARSER_FIELD_I(name, type, var, rw) -# define SENF_PARSE_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro) +# define SENF_PARSE_FIELD_var(name, type) SENF_PARSER_FIELD_I(name, type, var, rw, public) +# define SENF_PARSE_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro, public) # -# define SENF_PARSE_FIELD_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, rw) -# define SENF_PARSE_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro) +# define SENF_PARSE_FIELD_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, rw, public) +# define SENF_PARSE_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, public) # -# define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype) \ +# define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, access) \ + access: \ SENF_PARSER_I_BITFIELD_RESET() \ - SENF_PARSER_I_FIELD_INTRO(name, type) \ - BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type) \ - BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type) \ + SENF_PARSER_I_FIELD_INTRO(name, type, access) \ + BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type, access) \ + BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \ BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) ( \ name, type, \ BOOST_PP_CAT(SENF_PARSER_I_SIZE_, ofstype) (name, type), \ - BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type) ) \ - BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype) + BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type), \ + access ) \ + BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype, access) \ + public: # # //////////////////////////////////////// # // SENF_PARSER_I_FIELD_INTRO # -# define SENF_PARSER_I_FIELD_INTRO(name, type) \ +# define SENF_PARSER_I_FIELD_INTRO(name, type, access) \ typedef type BOOST_PP_CAT(name, _t); \ static size_type const BOOST_PP_CAT(name,_index) = SENF_MPL_SLOT_GET(index)+1; \ private: \ SENF_MPL_SLOT_SET(index, BOOST_PP_CAT(name,_index)); \ - public: + access: # # //////////////////////////////////////// # // SENF_PARSER_I_FIELD_INIT_* # -# define SENF_PARSER_I_FIELD_INIT_rw(name, type) \ +# define SENF_PARSER_I_FIELD_INIT_rw(name, type, access) \ private: \ void init_chain(senf::mpl::rv*) { \ init_chain(static_cast*>(0)); \ name().init(); \ } \ - public: + access: # -# define SENF_PARSER_I_FIELD_INIT_ro(name, type) \ +# define SENF_PARSER_I_FIELD_INIT_ro(name, type, access) \ private: \ void init_chain(senf::mpl::rv*) { \ init_chain(static_cast*>(0)); \ } \ - public: + access: # -# define SENF_PARSER_I_FIELD_OFS_var(name, type) \ +# //////////////////////////////////////// +# // SENF_PARSER_I_FIELD_OFS_* +# +# define SENF_PARSER_I_FIELD_OFS_var(name, type, access) \ size_type BOOST_PP_CAT(name,_offset)() const { \ return field_offset_(static_cast*>(0)); \ } # -# //////////////////////////////////////// -# // SENF_PARSER_I_FIELD_OFS_* -# -# define SENF_PARSER_I_FIELD_OFS_fix(name, type) \ +# define SENF_PARSER_I_FIELD_OFS_fix(name, type, access) \ static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset); # -# define SENF_PARSER_FINALIZE_GENERIC(name) \ - void defaultInit() { \ - init_chain(static_cast*>(0)); \ - } \ - name(data_iterator i, state_type s) : parser_base_type(i,s) {} \ - private: \ - template void init(T) { defaultInit(); } \ - public: \ - void init() { init(0); } -# # //////////////////////////////////////// # // SENF_PARSER_I_ADVANCE_OFS_* # -# define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(name()) +# // Can't call 'name()' here if 'name' is an ro field ... +# define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(parse(BOOST_PP_CAT(name,_offset)())) # define SENF_PARSER_I_INITBYTES_var(name, type) senf::init_bytes::value # # define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes # define SENF_PARSER_I_INITBYTES_fix(name, type) void # -# define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize) \ +# define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, access) \ size_type BOOST_PP_CAT(name, _next_offset)() const { \ return BOOST_PP_CAT(name,_offset)() + size; \ } \ @@ -170,14 +164,14 @@ return BOOST_PP_CAT(name, _next_offset)(); \ } \ SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes)); \ - public: + access: # -# define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize) \ +# define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, access) \ static size_type const BOOST_PP_CAT(name, _next_offset) = \ BOOST_PP_CAT(name, _offset) + size; \ private: \ SENF_MPL_SLOT_SET(offset, BOOST_PP_CAT(name, _next_offset)); \ - public: + access: # # //////////////////////////////////////// # // SENF_PARSER_I_FIELD_VAL_* @@ -185,17 +179,17 @@ # define SENF_PARSER_I_MAYBECALL_var() () # define SENF_PARSER_I_MAYBECALL_fix() # -# define SENF_PARSER_I_FIELD_VAL_rw(name,type,ofstype) \ +# define SENF_PARSER_I_FIELD_VAL_rw(name, type, ofstype, access) \ BOOST_PP_CAT(name, _t) name() const { \ return parse( \ BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)()); \ } # -# define SENF_PARSER_I_FIELD_VAL_ro(name,type,ofstype) \ +# define SENF_PARSER_I_FIELD_VAL_ro(name, type, ofstype, access) \ BOOST_PP_CAT(name, _t)::value_type name() const { \ return parse( \ - BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)() \ - .value() \ + BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)()) \ + .value(); \ } # # /////////////////////////////////////////////////////////////////////////// @@ -208,24 +202,24 @@ # # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype) \ SENF_PARSER_I_BITFIELD_RESET() \ - SENF_PARSER_I_FIELD_INTRO(name, type) \ - SENF_PARSER_I_FIELD_INIT_ro(name, type) \ - BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type) \ - BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize) \ + SENF_PARSER_I_FIELD_INTRO(name, type, public) \ + SENF_PARSER_I_FIELD_INIT_ro(name, type, public) \ + BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public) \ + BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, public) \ BOOST_PP_CAT(name, _t) name() const # # /////////////////////////////////////////////////////////////////////////// # // SENF_PARSE_BITFIELD_* # # define SENF_PARSE_BITFIELD_var(name, bits, type) \ - SENF_PARSER_BITFIELD_I(name, bits, type, var, rw) + SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public) # define SENF_PARSE_BITFIELD_RO_var(name, bits, type) \ - SENF_PARSER_BITFIELD_I(name, bits, type, var, ro) + SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public) # # define SENF_PARSE_BITFIELD_fix(name, bits, type) \ - SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw) + SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public) # define SENF_PARSE_BITFIELD_RO_fix(name, bits, type) \ - SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro) + SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public) # # //////////////////////////////////////// # // SENF_PARSER_BITFIELD_I @@ -234,37 +228,41 @@ # define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::Parse_UIntField # define SENF_PARSER_BITFIELD_TYPE_bool(start, bits) senf::Parse_Flag # -# define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype) \ +# define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access) \ + access: \ static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit); \ private: \ SENF_MPL_SLOT_SET(bit, BOOST_PP_CAT(name, _bit) + bits); \ typedef BOOST_PP_CAT(SENF_PARSER_BITFIELD_TYPE_, type)( BOOST_PP_CAT(name, _bit), bits ) \ BOOST_PP_CAT(name,_bit_t ); \ - public: \ - SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype) + access: \ + SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \ + public: # -# define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype) \ - SENF_PARSER_I_FIELD_INTRO(name, type) \ - SENF_PARSER_I_FIELD_INIT_ro(name, type) \ - BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type) \ +# define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype, access) \ + SENF_PARSER_I_FIELD_INTRO(name, type, access) \ + SENF_PARSER_I_FIELD_INIT_ro(name, type, access) \ + BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type, access) \ BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) ( \ name, type, \ - BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes ) \ + BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes, \ + access) \ private: \ SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes); \ - public: \ - BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype) + access: \ + BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype, access) \ + public: # # //////////////////////////////////////// # // SENF_PARSER_I_BITFIELD_OFS_* # -# define SENF_PARSER_I_BITFIELD_OFS_var(name, type) \ +# define SENF_PARSER_I_BITFIELD_OFS_var(name, type, access) \ size_type BOOST_PP_CAT(name,_offset)() const { \ return field_offset_(static_cast*>(0)) \ - SENF_MPL_SLOT_GET(bitfield_size); \ } # -# define SENF_PARSER_I_BITFIELD_OFS_fix(name, type) \ +# define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access) \ static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset) \ - SENF_MPL_SLOT_GET(bitfield_size); # @@ -289,17 +287,86 @@ SENF_PARSER_FINALIZE_GENERIC(name) \ static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset); # -# define SENF_PARSER_SKIP_var -# define SENF_PARSER_SKIP_fix +# define SENF_PARSER_FINALIZE_GENERIC(name) \ + void defaultInit() { \ + init_chain(static_cast*>(0)); \ + } \ + name(data_iterator i, state_type s) : parser_base_type(i,s) {} \ + private: \ + template void init(T) { defaultInit(); } \ + public: \ + void init() { init(0); } +# +# /////////////////////////////////////////////////////////////////////////// +# // SENF_PARSER_SKIP_* # -# define SENF_PARSER_GOTO_var -# define SENF_PARSER_GOTO_fix +# define SENF_PARSER_SKIP_var(bytes, ibytes) \ + SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var) # -# define SENF_PARSER_GOTO_OFFSET_var -# define SENF_PARSER_GOTO_OFFSET_fix +# define SENF_PARSER_SKIP_fix(bytes) \ + SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix) # -# define SENF_PARSER_LABEL_var -# define SENF_PARSER_LABEL_fix +# define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype) \ + private: \ + SENF_PARSER_I_BITFIELD_RESET() \ + SENF_PARSER_I_FIELD_INTRO(name, void, private) \ + SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \ + BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \ + BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, private) \ + public: +# +# /////////////////////////////////////////////////////////////////////////// +# // SENF_PARSER_GOTO_* +# +# define SENF_PARSER_GOTO_var(name) \ + SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), \ + BOOST_PP_CAT(name, _offset)(), \ + BOOST_PP_CAT(name, _init_bytes), \ + var ) +# +# define SENF_PARSER_GOTO_fix(name) \ + SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), \ + BOOST_PP_CAT(name, _offset), \ + BOOST_PP_CAT(name, _offset), \ + fix ) +# +# define SENF_PARSER_GOTO_OFFSET_var(offset, isize) \ + SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var ) +# +# define SENF_PARSER_GOTO_OFFSET_fix(offset) \ + SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix ) +# +# define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype) \ + private: \ + SENF_PARSER_I_BITFIELD_RESET() \ + SENF_PARSER_I_FIELD_INTRO(name, void, private) \ + SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \ + BOOST_PP_CAT( SENF_PARSE_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize) \ + public: +# +# define SENF_PARSE_I_GOTO_SET_OFS_var(name, offs, initsize) \ + size_type field_offset_(senf::mpl::rv*) const { \ + return offs; \ + } \ + SENF_MPL_SLOT_SET(init_bytes, initsize); +# +# define SENF_PARSE_I_GOTO_SET_OFS_fix(name, offs, initsize) \ + SENF_MPL_SLOT_SET(offset, offs); +# +# /////////////////////////////////////////////////////////////////////////// +# // SENF_PARSER_LABEL_* +# +# define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public ) +# define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public ) +# +# define SENF_PARSER_I_LABEL(name, ofstype, access) \ + access: \ + SENF_PARSER_I_BITFIELD_RESET() \ + SENF_PARSER_I_FIELD_INTRO(name, void, access) \ + SENF_PARSER_I_FIELD_INIT_ro(name, void, access) \ + BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \ + BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0,access) \ + public: # # ////////////////////////////////ih.e/////////////////////////////////////// # endif diff --git a/Packets/ParseHelpers.test.cc b/Packets/ParseHelpers.test.cc new file mode 100644 index 0000000..6d69414 --- /dev/null +++ b/Packets/ParseHelpers.test.cc @@ -0,0 +1,262 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund +// +// 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 ParseHelpers.test unit tests */ + +//#include "ParseHelpers.test.hh" +//#include "ParseHelpers.test.ih" + +// Custom includes +#include "Packets.hh" + +#include +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +namespace { + + struct FixedBaseParser : public senf::PacketParserBase + { +# include SENF_FIXED_PARSER() + + SENF_PARSE_FIELD ( normalField , senf::Parse_UInt16 ); + SENF_PARSE_FIELD_RO ( roField , senf::Parse_UInt16 ); + + SENF_PARSE_CUSTOM_FIELD ( customField , int, 2 ) { + return parse(customField_offset); + } + + SENF_PARSE_BITFIELD ( signedBitfield , 4, signed ); + SENF_PARSE_BITFIELD ( unsignedBitfield , 3, unsigned ); + SENF_PARSE_BITFIELD ( boolBitfield , 1, bool ); + + SENF_PARSE_BITFIELD_RO ( roSignedBitfield , 4, signed ); + SENF_PARSE_BITFIELD_RO ( roUnsignedBitfield , 3, unsigned ); + SENF_PARSE_BITFIELD_RO ( roBoolBitfield , 1, bool ); + + SENF_PARSER_LABEL( end ); + SENF_PARSER_GOTO( roField ); + + SENF_PARSE_FIELD ( overlayOfRoField , senf::Parse_Int16 ); + SENF_PARSER_SKIP( 2 ); + SENF_PARSE_FIELD ( overlayOfBitfield , senf::Parse_UInt8 ); + + SENF_PARSER_GOTO_OFFSET( 1 ); + + SENF_PARSE_FIELD ( lowbyteOfNormalField , senf::Parse_UInt8 ); + + SENF_PARSER_GOTO( end ); + + SENF_PARSER_FINALIZE( FixedBaseParser ); + }; + + struct FixedDerivedParser : public FixedBaseParser + { +# include SENF_FIXED_PARSER() + + SENF_PARSER_INHERIT( FixedBaseParser ); + + SENF_PARSE_FIELD ( derivedField , senf::Parse_UInt16 ); + + SENF_PARSER_LABEL( end ); + SENF_PARSER_GOTO( signedBitfield ); + + SENF_PARSE_FIELD ( anotherOverlay , senf::Parse_UInt16 ); + + SENF_PARSER_GOTO( end ); + + SENF_PARSER_FINALIZE( FixedDerivedParser ) + }; +} + +BOOST_AUTO_UNIT_TEST(fixedParser) +{ + unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x83, 0x84, 0x07, 0x08 }; + + senf::DataPacket p (senf::DataPacket::create(data)); + + FixedBaseParser baseParser (p.data().begin(), &p.data()); + + BOOST_CHECK_EQUAL( FixedBaseParser::fixed_bytes+0, 8u ); + + BOOST_CHECK_EQUAL ( baseParser.normalField() , 0x0102u ); + BOOST_CHECK_EQUAL ( baseParser.roField() , 0x0304u ); + BOOST_CHECK_EQUAL ( baseParser.customField() , 0x0506 ); + + BOOST_CHECK_EQUAL ( baseParser.signedBitfield() , -8 ); + BOOST_CHECK_EQUAL ( baseParser.unsignedBitfield() , 1u ); + BOOST_CHECK ( baseParser.boolBitfield() ); + + BOOST_CHECK_EQUAL ( baseParser.roSignedBitfield() , -8 ); + BOOST_CHECK_EQUAL ( baseParser.roUnsignedBitfield() , 2u ); + BOOST_CHECK ( ! baseParser.roBoolBitfield() ); + + BOOST_CHECK_EQUAL ( baseParser.overlayOfRoField() , 0x0304 ); + BOOST_CHECK_EQUAL ( baseParser.overlayOfBitfield() , 0x83u ); + BOOST_CHECK_EQUAL ( baseParser.lowbyteOfNormalField() , 0x02u ); + + FixedDerivedParser derivedParser (p.data().begin(), &p.data()); + + BOOST_CHECK_EQUAL( FixedDerivedParser::fixed_bytes+0, 10u ); + + BOOST_CHECK_EQUAL ( derivedParser.normalField() , 0x0102u ); + BOOST_CHECK_EQUAL ( derivedParser.roField() , 0x0304u ); + BOOST_CHECK_EQUAL ( derivedParser.customField() , 0x0506 ); + + BOOST_CHECK_EQUAL ( derivedParser.signedBitfield() , -8 ); + BOOST_CHECK_EQUAL ( derivedParser.unsignedBitfield() , 1u ); + BOOST_CHECK ( derivedParser.boolBitfield() ); + + BOOST_CHECK_EQUAL ( derivedParser.roSignedBitfield() , -8 ); + BOOST_CHECK_EQUAL ( derivedParser.roUnsignedBitfield() , 2u ); + BOOST_CHECK ( ! derivedParser.roBoolBitfield() ); + + BOOST_CHECK_EQUAL ( derivedParser.overlayOfRoField() , 0x0304 ); + BOOST_CHECK_EQUAL ( derivedParser.overlayOfBitfield() , 0x83u ); + BOOST_CHECK_EQUAL ( derivedParser.lowbyteOfNormalField() , 0x02u ); + + BOOST_CHECK_EQUAL ( derivedParser.derivedField() , 0x0708u ); + BOOST_CHECK_EQUAL ( derivedParser.anotherOverlay() , 0x8384u ); +} + +namespace { + + struct VariableBaseParser : public senf::PacketParserBase + { +# include SENF_PARSER() + + SENF_PARSE_FIELD ( normalField , senf::Parse_UInt16 ); + SENF_PARSE_FIELD_RO ( roField , senf::Parse_UInt16 ); + + SENF_PARSE_CUSTOM_FIELD ( customField , int, 2, 2 ) { + return parse(customField_offset()); + } + + SENF_PARSE_BITFIELD ( signedBitfield , 4, signed ); + SENF_PARSE_BITFIELD ( unsignedBitfield , 3, unsigned ); + SENF_PARSE_BITFIELD ( boolBitfield , 1, bool ); + + SENF_PARSE_BITFIELD_RO ( roSignedBitfield , 4, signed ); + SENF_PARSE_BITFIELD_RO ( roUnsignedBitfield , 3, unsigned ); + SENF_PARSE_BITFIELD_RO ( roBoolBitfield , 1, bool ); + + SENF_PARSER_LABEL( end ); + SENF_PARSER_GOTO( roField ); + + SENF_PARSE_FIELD ( overlayOfRoField , senf::Parse_Int16 ); + SENF_PARSER_SKIP( 2, 2 ); + SENF_PARSE_FIELD ( overlayOfBitfield , senf::Parse_UInt8 ); + + SENF_PARSER_GOTO_OFFSET( 1, 1 ); + + SENF_PARSE_FIELD ( lowbyteOfNormalField , senf::Parse_UInt8 ); + + SENF_PARSER_GOTO( end ); + + SENF_PARSER_FINALIZE( VariableBaseParser ); + }; + + struct VariableDerivedParser : public VariableBaseParser + { +# include SENF_PARSER() + + SENF_PARSER_INHERIT( VariableBaseParser ); + + SENF_PARSE_FIELD ( derivedField , senf::Parse_UInt16 ); + + SENF_PARSER_LABEL( end ); + SENF_PARSER_GOTO( signedBitfield ); + + SENF_PARSE_FIELD ( anotherOverlay , senf::Parse_UInt16 ); + + SENF_PARSER_GOTO( end ); + + SENF_PARSER_FINALIZE( VariableDerivedParser ); + }; +} + +BOOST_AUTO_UNIT_TEST(variableParser) +{ + unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x83, 0x84, 0x07, 0x08 }; + + senf::DataPacket p (senf::DataPacket::create(data)); + + VariableBaseParser baseParser (p.data().begin(), &p.data()); + + BOOST_CHECK_EQUAL ( senf::bytes(baseParser), 8u ); + + BOOST_CHECK_EQUAL ( baseParser.normalField() , 0x0102u ); + BOOST_CHECK_EQUAL ( baseParser.roField() , 0x0304u ); + BOOST_CHECK_EQUAL ( baseParser.customField() , 0x0506 ); + + BOOST_CHECK_EQUAL ( baseParser.signedBitfield() , -8 ); + BOOST_CHECK_EQUAL ( baseParser.unsignedBitfield() , 1u ); + BOOST_CHECK ( baseParser.boolBitfield() ); + + BOOST_CHECK_EQUAL ( baseParser.roSignedBitfield() , -8 ); + BOOST_CHECK_EQUAL ( baseParser.roUnsignedBitfield() , 2u ); + BOOST_CHECK ( ! baseParser.roBoolBitfield() ); + + BOOST_CHECK_EQUAL ( baseParser.overlayOfRoField() , 0x0304 ); + BOOST_CHECK_EQUAL ( baseParser.overlayOfBitfield() , 0x83u ); + BOOST_CHECK_EQUAL ( baseParser.lowbyteOfNormalField() , 0x02u ); + + VariableDerivedParser derivedParser (p.data().begin(), &p.data()); + + BOOST_CHECK_EQUAL ( senf::bytes(derivedParser), 10u ); + + BOOST_CHECK_EQUAL ( derivedParser.normalField() , 0x0102u ); + BOOST_CHECK_EQUAL ( derivedParser.roField() , 0x0304u ); + BOOST_CHECK_EQUAL ( derivedParser.customField() , 0x0506 ); + + BOOST_CHECK_EQUAL ( derivedParser.signedBitfield() , -8 ); + BOOST_CHECK_EQUAL ( derivedParser.unsignedBitfield() , 1u ); + BOOST_CHECK ( derivedParser.boolBitfield() ); + + BOOST_CHECK_EQUAL ( derivedParser.roSignedBitfield() , -8 ); + BOOST_CHECK_EQUAL ( derivedParser.roUnsignedBitfield() , 2u ); + BOOST_CHECK ( ! derivedParser.roBoolBitfield() ); + + BOOST_CHECK_EQUAL ( derivedParser.overlayOfRoField() , 0x0304 ); + BOOST_CHECK_EQUAL ( derivedParser.overlayOfBitfield() , 0x83u ); + BOOST_CHECK_EQUAL ( derivedParser.lowbyteOfNormalField() , 0x02u ); + + BOOST_CHECK_EQUAL ( derivedParser.derivedField() , 0x0708u ); + BOOST_CHECK_EQUAL ( derivedParser.anotherOverlay() , 0x8384u ); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// 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: