switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / ListBParser.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
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 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief ListBParser unit tests */
30
31 //#include "ListBParser.test.hh"
32 //#include "ListBParser.test.ih"
33
34 // Custom includes
35 #include "Packets.hh"
36
37 #include <senf/Utils/auto_unit_test.hh>
38 #include <boost/test/test_tools.hpp>
39
40 #define prefix_
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42
43 namespace {
44     struct VoidPacket : public senf::PacketTypeBase
45     {};
46
47     struct VectorParser : public senf::PacketParserBase
48     {
49 #       include SENF_PARSER()
50
51         SENF_PARSER_PRIVATE_FIELD( size, senf::UInt8Parser );
52         SENF_PARSER_VECTOR( vec, size, senf::UInt16Parser );
53
54         SENF_PARSER_FINALIZE(VectorParser);
55
56         typedef std::vector<boost::uint16_t> value_type;
57
58         value_type value() const {
59             value_type v (vec().begin(), vec().end());
60             return v;
61         }
62         void value(value_type const & v) {
63             vec_t::container container (vec());
64             container.clear();
65             for (value_type::const_iterator i=v.begin(); i!=v.end(); ++i)
66                 container.push_back( *i);
67         }
68         operator value_type() const { return value(); }
69         VectorParser const & operator= (value_type const & other) { value(other); return *this; }
70     };
71
72     typedef senf::ListParser<
73         senf::detail::ListBParser_Policy<
74             VectorParser,
75             senf::detail::PrefixAuxParserPolicy<senf::UInt16Parser> > > MyListBParser;
76 }
77
78 SENF_AUTO_UNIT_TEST(ListBParser)
79 {
80     senf::PacketInterpreterBase::ptr pi (senf::PacketInterpreter<VoidPacket>::create(
81             MyListBParser::init_bytes));
82
83     MyListBParser p (pi->data().begin(),&pi->data());
84     p.init();
85     BOOST_CHECK_EQUAL( p.size(), 0u );
86     BOOST_CHECK_EQUAL( p.bytes(), 2u );
87     BOOST_CHECK( p.empty() );
88
89     // the mutators are really tested together with the container wrappers since they are based
90     // on the container wrapper. Here we only need one call to make the list larger ...
91
92     p.push_back_space();
93     p = MyListBParser(pi->data().begin(),&pi->data());
94     BOOST_CHECK_EQUAL( p.bytes(), 3u );
95     BOOST_CHECK_EQUAL( p.size(), 1u );
96     BOOST_CHECK( ! p.empty() );
97 }
98
99 SENF_AUTO_UNIT_TEST(ListBParser_container)
100 {
101     senf::PacketInterpreterBase::ptr pi (senf::PacketInterpreter<VoidPacket>::create(
102             MyListBParser::init_bytes));
103
104     {
105         MyListBParser::container c (MyListBParser(pi->data().begin(),&pi->data()));
106
107         BOOST_CHECK_EQUAL( c.size(), 0u );
108         BOOST_CHECK_EQUAL( c.bytes(), 2u );
109         BOOST_CHECK( c.begin() == c.end() );
110
111         c.shift(c.begin());
112         BOOST_CHECK_EQUAL( c.size(), 1u );
113         BOOST_CHECK_EQUAL( c.bytes(), 3u );
114
115         BOOST_CHECK_EQUAL( c.front().vec().size(), 0u );
116         c.front().vec().push_back(0x1234u);
117         BOOST_CHECK_EQUAL( c.bytes(), 5u );
118
119         {
120             senf::PacketInterpreterBase::ptr pi2 (senf::PacketInterpreter<VoidPacket>::create(
121                     MyListBParser::init_bytes));
122             MyListBParser::container c2 (MyListBParser(pi2->data().begin(),&pi2->data()));
123             {
124                 VectorParser::vec_t::container c2v (c2.push_back_space().vec());
125                 c2v.push_back(0x2345u);
126                 c2v.push_back(0x3456u);
127             }
128
129             BOOST_CHECK_EQUAL(c2.size(), 1u);
130             BOOST_CHECK_EQUAL(c2.bytes(), 7u);
131
132             c.insert(c.end(),c2.back());
133             BOOST_CHECK_EQUAL( c.size(), 2u );
134             BOOST_CHECK_EQUAL( c.bytes(), 10u );
135             BOOST_CHECK_EQUAL( c.back().vec()[0], 0x2345u );
136             BOOST_CHECK_EQUAL( c.back().bytes(), c2.back().bytes() );
137
138             c2.back().vec()[0] << 0x1357u;
139             c.insert(boost::next(c.begin()), 2u, c2.back());
140             BOOST_CHECK_EQUAL( c.size(), 4u );
141             BOOST_CHECK_EQUAL( c.bytes(), 20u );
142             BOOST_CHECK_EQUAL( (*boost::next(c.begin())).vec()[0], 0x1357u );
143             BOOST_CHECK_EQUAL( (*boost::next(c.begin(),2)).vec()[0], 0x1357u );
144
145             c2.back().vec()[0] << 0x2468u;
146             c.insert(c.begin(),c2.begin(),c2.end());
147             BOOST_CHECK_EQUAL( c.size(), 5u );
148             BOOST_CHECK_EQUAL( c.bytes(), 25u );
149             BOOST_CHECK_EQUAL( c.front().vec()[0], 0x2468u );
150
151             c.erase(c.begin(),2);
152             BOOST_CHECK_EQUAL( c.size(), 3u );
153             BOOST_CHECK_EQUAL( c.bytes(), 17u );
154             BOOST_CHECK_EQUAL( c.front().vec()[0],0x1357u );
155             BOOST_CHECK_EQUAL( c.back().vec()[0], 0x2345u );
156
157             c.erase((boost::next(c.begin(),2)),c.end());
158             BOOST_CHECK_EQUAL( c.size(), 2u );
159             BOOST_CHECK_EQUAL( c.bytes(), 12u );
160             BOOST_CHECK_EQUAL( c.front().vec()[0],0x1357u );
161             BOOST_CHECK_EQUAL( c.back().vec()[0], 0x1357u );
162
163             c.clear();
164             BOOST_CHECK_EQUAL( c.size(), 0u );
165             BOOST_CHECK_EQUAL( c.bytes(), 2u );
166        }
167     }
168 }
169
170 namespace {
171
172     struct TestTransform
173     {
174         typedef unsigned value_type;
175         static unsigned get(unsigned v) { return v/2; }
176         static unsigned set(unsigned v) { return 2*v; }
177     };
178
179     struct TestListParser
180         : public senf::PacketParserBase
181     {
182 #       include SENF_PARSER()
183
184         SENF_PARSER_PRIVATE_FIELD ( size1 , senf::UInt8Parser );
185         SENF_PARSER_PRIVATE_FIELD ( size2 , senf::UInt8Parser );
186         SENF_PARSER_FIELD         ( dummy , senf::UInt32Parser );
187         SENF_PARSER_LIST          ( list1  , bytes(size1) , VectorParser );
188         SENF_PARSER_LIST          ( list2  , transform(TestTransform, bytes(size2)) ,
189                                              VectorParser );
190
191         SENF_PARSER_FINALIZE(TestListParser);
192     };
193
194     struct TestListPacketType
195         : public senf::PacketTypeBase,
196           public senf::PacketTypeMixin<TestListPacketType>
197     {
198         typedef senf::PacketTypeMixin<TestListPacketType> mixin;
199         typedef senf::ConcretePacket<TestListPacketType> packet;
200         typedef TestListParser parser;
201
202         using mixin::nextPacketRange;
203         using mixin::initSize;
204         using mixin::init;
205     };
206     typedef senf::ConcretePacket<TestListPacketType> TestListPacket;
207
208 }
209
210 SENF_AUTO_UNIT_TEST(listBytesMacro)
211 {
212     unsigned char data[] = {    8,                   // size1
213                                18,                   // size2
214                              0x01, 0x02, 0x03, 0x04, // dummy
215                              0x01,                   // list1()[0].size()
216                              0x05, 0x06,             // list1().vec()[0]
217                              0x02,                   // list1()[1].size()
218                              0x07, 0x08,             // list1()[1].vec()[0]
219                              0x09, 0x0A,             // list1()[1].vec()[1]
220                              0x00,                   // list2()[0].size()
221                              0x02,                   // list2()[1].size()
222                              0x0B, 0x0C,             // list2()[1].vec()[0]
223                              0x0D, 0x0E,             // list2()[1].vec()[1]
224                              0x01,                   // list2()[2].size()
225                              0x0F, 0x10 };           // list2()[2].vec()[0]
226
227     senf::DataPacket p (senf::DataPacket::create(data));
228     TestListParser parser (p.data().begin(), &p.data());
229
230     BOOST_CHECK_EQUAL( parser.list1().size(), 2u );
231     BOOST_CHECK_EQUAL( parser.list2().size(), 3u );
232     BOOST_CHECK_EQUAL( parser.dummy(), 0x01020304u );
233
234     TestListParser::list2_t::container list2 (parser.list2());
235
236     {
237         TestListParser::list1_t::container list (parser.list1());
238         BOOST_CHECK_EQUAL( list.size(), 2u );
239
240         TestListParser::list1_t::container::iterator i (list.begin());
241         BOOST_CHECK_EQUAL( i->vec().size(), 1u );
242         BOOST_CHECK_EQUAL( i->vec()[0], 0x0506u );
243
244         ++i;
245         BOOST_CHECK_EQUAL( i->vec().size(), 2u );
246         BOOST_CHECK_EQUAL( i->vec()[0], 0x0708u );
247         BOOST_CHECK_EQUAL( i->vec()[1], 0x090Au );
248
249         ++i;
250         BOOST_CHECK( i == list.end() );
251     }
252
253     {
254         TestListParser::list2_t::container list (parser.list2());
255         BOOST_CHECK_EQUAL( list.size(), 3u );
256
257         TestListParser::list2_t::container::iterator i (list.begin());
258         BOOST_CHECK_EQUAL( i->vec().size(), 0u );
259
260         ++i;
261         BOOST_CHECK_EQUAL( i->vec().size(), 2u );
262         BOOST_CHECK_EQUAL( i->vec()[0], 0x0B0Cu );
263         BOOST_CHECK_EQUAL( i->vec()[1], 0x0D0Eu );
264
265         ++i;
266         BOOST_CHECK_EQUAL( i->vec().size(), 1u );
267         BOOST_CHECK_EQUAL( i->vec()[0], 0x0F10u );
268
269         ++i;
270         BOOST_CHECK( i == list.end() );
271     }
272
273 }
274
275 namespace {
276
277     struct TestPacketSizeList
278         : public senf::PacketParserBase
279     {
280 #       include SENF_PARSER()
281
282         SENF_PARSER_LIST ( list, packetSize(), VectorParser );
283
284         SENF_PARSER_FINALIZE(TestPacketSizeList);
285     };
286 }
287
288 SENF_AUTO_UNIT_TEST(listBytesParser_packetSize)
289 {
290     unsigned char data[] = { 0x01,                   // list()[0].vec().size()
291                              0x05, 0x06,             // list()[0].vec()[0]
292                              0x02,                   // list()[1].vec().size()
293                              0x07, 0x08,             // list()[1].vec()[0]
294                              0x09, 0x0A,             // list()[1].vec()[1]
295                              0x00,                   // list()[2].vec().size()
296                              0x02,                   // list()[3].vec().size()
297                              0x0B, 0x0C,             // list()[3].vec()[0]
298                              0x0D, 0x0E,             // list()[3].vec()[1]
299                              0x01,                   // list()[4].vec().size()
300                              0x0F, 0x10 };           // list()[4].vec()[0]
301
302     senf::DataPacket p (senf::DataPacket::create(data));
303
304     {
305         TestPacketSizeList l (p.data().begin(), &p.data());
306         BOOST_CHECK_EQUAL( l.list().size(), 5u );
307
308         TestPacketSizeList::list_t::container c (l.list());
309         TestPacketSizeList::list_t::container::iterator i (c.begin());
310
311         senf::UInt16Parser::value_type vec0[] = { 0x0506 };
312         senf::UInt16Parser::value_type vec1[] = { 0x0708, 0x090A };
313         senf::UInt16Parser::value_type vec2[] = {};
314         senf::UInt16Parser::value_type vec3[] = { 0x0B0C, 0x0D0E };
315         senf::UInt16Parser::value_type vec4[] = { 0x0F10 };
316
317         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
318                                        vec0, vec0+sizeof(vec0)/sizeof(vec0[0]) );
319         ++ i;
320         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
321                                        vec1, vec1+sizeof(vec1)/sizeof(vec1[0]) );
322         ++ i;
323         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
324                                        vec2, vec2+sizeof(vec2)/sizeof(vec2[0]) );
325         ++ i;
326         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
327                                        vec3, vec3+sizeof(vec3)/sizeof(vec3[0]) );
328
329         ++ i;
330         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
331                                        vec4, vec4+sizeof(vec4)/sizeof(vec4[0]) );
332
333         ++ i;
334         BOOST_CHECK( i == c.end() );
335
336         i = c.begin();
337         ++i;
338         TestPacketSizeList::list_t::value_type::vec_t::container v (i->vec());
339         v.push_back(0xFEFF);
340     }
341
342     {
343         TestPacketSizeList l (p.data().begin(), &p.data());
344         BOOST_CHECK_EQUAL( l.list().size(), 5u );
345         BOOST_CHECK_EQUAL( l.list().bytes(), p.data().size() );
346
347         TestPacketSizeList::list_t::container c (l.list());
348         TestPacketSizeList::list_t::container::iterator i (c.begin());
349
350         senf::UInt16Parser::value_type vec0[] = { 0x0506 };
351         senf::UInt16Parser::value_type vec1[] = { 0x0708, 0x090A, 0xFEFF };
352         senf::UInt16Parser::value_type vec2[] = {};
353         senf::UInt16Parser::value_type vec3[] = { 0x0B0C, 0x0D0E };
354         senf::UInt16Parser::value_type vec4[] = { 0x0F10 };
355
356         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
357                                        vec0, vec0+sizeof(vec0)/sizeof(vec0[0]) );
358         ++ i;
359         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
360                                        vec1, vec1+sizeof(vec1)/sizeof(vec1[0]) );
361         ++ i;
362         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
363                                        vec2, vec2+sizeof(vec2)/sizeof(vec2[0]) );
364         ++ i;
365         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
366                                        vec3, vec3+sizeof(vec3)/sizeof(vec3[0]) );
367
368         ++ i;
369         BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(),
370                                        vec4, vec4+sizeof(vec4)/sizeof(vec4[0]) );
371         ++ i;
372         BOOST_CHECK( i == c.end() );
373     }
374 }
375
376 SENF_AUTO_UNIT_TEST(listBytesMacro_stress)
377 {
378     TestListPacket testListPacket (TestListPacket::create());
379     for (unsigned i=0; i<12; ++i) {
380         VectorParser::value_type vec( 4, 42);
381         testListPacket->list2().push_back( vec);
382     }
383     BOOST_CHECK_EQUAL( testListPacket->list2().size(), 12u );
384
385 }
386
387 //-/////////////////////////////////////////////////////////////////////////////////////////////////
388 #undef prefix_
389
390 \f
391 // Local Variables:
392 // mode: c++
393 // fill-column: 100
394 // comment-column: 40
395 // c-file-style: "senf"
396 // indent-tabs-mode: nil
397 // ispell-local-dictionary: "american"
398 // compile-command: "scons -u test"
399 // End: