minor fixes for clang++
[senf.git] / senf / Packets / GenericTLV.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2009
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Thorsten Horstmann <tho@berlios.de>
27
28 /** \file
29     \brief GenericTLV unit tests */
30
31 // Custom includes
32 #include "GenericTLV.hh"
33 #include <senf/Packets/DefaultBundle/IPv6Extensions.hh>
34
35 #include <senf/Utils/auto_unit_test.hh>
36 #include <boost/test/test_tools.hpp>
37
38 #define prefix_
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40
41 namespace {
42     struct MyTLVParserBase
43         : public senf::PacketParserBase
44     {
45 #       include SENF_PARSER()
46         SENF_PARSER_FIELD    ( type,   senf::UInt8Parser );
47         SENF_PARSER_FIELD_RO ( length, senf::UInt8Parser );
48         SENF_PARSER_FINALIZE ( MyTLVParserBase           );
49
50         typedef senf::GenericTLVParserRegistry<MyTLVParserBase> Registry;
51     };
52
53     struct MyGenericTLVParser
54         : public senf::GenericTLVParserBase<MyTLVParserBase>
55     {
56         typedef senf::GenericTLVParserBase<MyTLVParserBase> base;
57         MyGenericTLVParser(data_iterator i, state_type s) : base(i,s) {}
58     };
59
60    struct MyConcreteTLVParser
61        : public MyTLVParserBase
62    {
63    #   include SENF_PARSER()
64        SENF_PARSER_INHERIT  ( MyTLVParserBase             );
65        SENF_PARSER_FIELD    ( myValue, senf::UInt32Parser );
66        SENF_PARSER_FINALIZE ( MyConcreteTLVParser         );
67
68        SENF_PARSER_INIT() {
69            type() = typeId;
70            length_() = 4;
71        }
72        static type_t::value_type const typeId = 0x42;
73
74        void dump(std::ostream & os) const {
75            boost::io::ios_all_saver ias(os);
76            os << "  MyConcreteTLVParser\n"
77               << "    type:   " << senf::format::dumpint(type()) << "\n"
78               << "    length: " << senf::format::dumpint(length()) << "\n"
79               << "    value:  " << senf::format::dumpint(myValue()) << "\n";
80        }
81    };
82
83    struct MyConcrete2TLVParser
84        : public MyTLVParserBase
85    {
86    #   include SENF_PARSER()
87        SENF_PARSER_INHERIT  ( MyTLVParserBase             );
88        SENF_PARSER_FIELD    ( myValue, senf::UInt32Parser );
89        SENF_PARSER_FINALIZE ( MyConcrete2TLVParser         );
90
91        SENF_PARSER_INIT() {
92            type() = typeId;
93            length_() = 4;
94        }
95        static type_t::value_type const typeId = 0x47;
96
97        void dump(std::ostream & os) const {
98            boost::io::ios_all_saver ias(os);
99            os << "  MyConcreteTLVParser\n"
100               << "    type:   " << senf::format::dumpint(type()) << "\n"
101               << "    length: " << senf::format::dumpint(length()) << "\n"
102               << "    value:  " << senf::format::dumpint(myValue()) << "\n";
103        }
104    };
105
106     class MyTestPacketParser
107         : public senf::PacketParserBase
108     {
109 #       include SENF_PARSER()
110         SENF_PARSER_FIELD_RO ( list_length, senf::UInt8Parser );
111         SENF_PARSER_LIST     ( tlv_list, list_length, MyGenericTLVParser );
112         SENF_PARSER_FINALIZE ( MyTestPacketParser );
113     };
114
115     struct MyTestPacketType
116         : public senf::PacketTypeBase,
117           public senf::PacketTypeMixin<MyTestPacketType>
118     {
119         typedef senf::PacketTypeMixin<MyTestPacketType> mixin;
120         typedef MyTestPacketParser parser;
121
122         using mixin::nextPacketRange;
123         using mixin::init;
124         using mixin::initSize;
125     };
126     typedef senf::ConcretePacket<MyTestPacketType> MyTestPacket;
127 }
128
129
130 SENF_AUTO_UNIT_TEST(GenericTLV_parser)
131 {
132     BOOST_CHECK_EQUAL( senf::init_bytes<MyGenericTLVParser>::value,
133             senf::init_bytes<MyTLVParserBase>::value) ;
134
135     unsigned char data[] = {
136             0x42, 0x04,             // type, length
137             0x00, 0x01, 0x02, 0x03  // value
138     };
139
140     senf::DataPacket dataPacket ( senf::DataPacket::create(data));
141     MyGenericTLVParser genericTLVParser (dataPacket.data().begin(), &dataPacket.data());
142
143     BOOST_CHECK_EQUAL( senf::bytes( genericTLVParser), sizeof(data) );
144     BOOST_CHECK_EQUAL( genericTLVParser.type(),   0x42 );
145     BOOST_CHECK_EQUAL( genericTLVParser.length(), 0x04 );
146     SENF_CHECK_EQUAL_COLLECTIONS( data+2, data+sizeof(data),
147             genericTLVParser.value().begin(), genericTLVParser.value().end() );
148     genericTLVParser.value( data );
149     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
150             genericTLVParser.value().begin(), genericTLVParser.value().end() );
151
152     std::vector<unsigned char> value (4, 0xab);
153     genericTLVParser.value( std::make_pair(0x42, value));
154
155     BOOST_CHECK( genericTLVParser.is<MyConcreteTLVParser>());
156
157     MyConcreteTLVParser concreteTLVParser ( genericTLVParser.as<MyConcreteTLVParser>());
158     BOOST_CHECK_EQUAL( concreteTLVParser.type(),   0x42 );
159     BOOST_CHECK_EQUAL( concreteTLVParser.length(), 0x04 );
160     BOOST_CHECK_EQUAL( concreteTLVParser.myValue(), 0xabababab );
161 }
162
163 SENF_AUTO_UNIT_TEST(GenericTLV_packet)
164 {
165     MyTestPacket p ( MyTestPacket::create());
166     MyTestPacket::Parser::tlv_list_t::container tlvContainer (p->tlv_list() );
167     MyConcreteTLVParser tlv ( tlvContainer.push_back_space().init<MyConcreteTLVParser>());
168     tlv.myValue() << 0xffff;
169     p.finalizeThis();
170
171     unsigned char data[] = {
172             0x01, // tlv list length
173             // first tlv:
174             0x42, 0x04,             // type, length
175             0x00, 0x00, 0xff, 0xff  // value
176     };
177     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
178             p.data().begin(), p.data().end() );
179 }
180
181
182 SENF_AUTO_UNIT_TEST(GenericTLV_registry)
183 {
184     typedef senf::GenericTLVParserRegistry<MyTLVParserBase> MyTLVParserRegistry;
185     MyTestPacket p ( MyTestPacket::create());
186     MyTestPacket::Parser::tlv_list_t::container tlvContainer (p->tlv_list() );
187     MyConcreteTLVParser conreteTLVParser (
188             tlvContainer.push_back_space().init<MyConcreteTLVParser>());
189     conreteTLVParser.myValue() << 0xffff;
190     p.finalizeThis();
191
192     std::stringstream ss;
193     tlvContainer.begin()->dump( ss);
194     BOOST_CHECK_EQUAL( ss.str().substr(0,58),
195             "  GenericTLVParser<(anonymous namespace)::MyTLVParserBase>" );
196     BOOST_CHECK( ! MyTLVParserRegistry::instance().isRegistered( tlvContainer.begin()->type()));
197
198     MyTLVParserRegistry::instance().registerParser<MyConcreteTLVParser>();
199     BOOST_CHECK( MyTLVParserRegistry::instance().isRegistered( tlvContainer.begin()->type()));
200     BOOST_CHECK_EQUAL(
201             MyTLVParserRegistry::instance().bytes( *tlvContainer.begin()),
202             senf::bytes( *tlvContainer.begin()) );
203
204     ss.str(""); ss.clear();
205
206     tlvContainer.begin()->dump( ss);
207     BOOST_CHECK_EQUAL( ss.str().substr(0,21), "  MyConcreteTLVParser" );
208 }
209
210 SENF_AUTO_UNIT_TEST(GenericTLV_predicate)
211 {
212     MyTestPacket p ( MyTestPacket::create() );
213     MyTestPacket::Parser::tlv_list_t::container tlvContainer (p->tlv_list() );
214     MyConcreteTLVParser conreteTLVParser (
215             tlvContainer.push_back_space().init<MyConcreteTLVParser>());
216     conreteTLVParser.myValue() << 0xffff;
217     MyConcrete2TLVParser conreteTLVParser2 (
218             tlvContainer.push_back_space().init<MyConcrete2TLVParser>());
219     conreteTLVParser2.myValue() << 0xdddd;
220     p.finalizeThis();
221
222 //     typedef senf::IPv6HopByHopOptionsPacket::Parser::options_t::container optContainer_t;
223 //     optContainer_t optC (p->tlv_list() );
224
225     MyTestPacket::Parser::tlv_list_t::container testTlvContainer (p->tlv_list() );
226     MyTestPacket::Parser::tlv_list_t::container::iterator it = std::find_if (
227       testTlvContainer.begin(), testTlvContainer.end(),
228       senf::detail::Predicate< senf::GenericTLVParserBase<MyTLVParserBase>, MyConcreteTLVParser>() );
229     BOOST_CHECK( it->is<MyConcreteTLVParser>()) ;
230 }
231
232 //-/////////////////////////////////////////////////////////////////////////////////////////////////
233 #undef prefix_
234
235 \f
236 // Local Variables:
237 // mode: c++
238 // fill-column: 100
239 // comment-column: 40
240 // c-file-style: "senf"
241 // indent-tabs-mode: nil
242 // ispell-local-dictionary: "american"
243 // compile-command: "scons -u test"
244 // End: