Fixed whitespace in all files (no tabs)
[senf.git] / Packets / ParseListS.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 // Unit tests
24
25 //#include "ParseListS.test.hh"
26 //#include "ParseListS.test.ih"
27
28 // Custom includes
29 #include "ParseListS.hh"
30 #include "ParseInt.hh"
31 #include "ParseVec.hh"
32
33 #include <boost/test/auto_unit_test.hpp>
34 #include <boost/test/test_tools.hpp>
35 #include <boost/assign.hpp>
36
37 #define prefix_
38 ///////////////////////////////cc.p////////////////////////////////////////
39
40 using namespace senf;
41
42 namespace {
43     template <class Value>
44     struct Sentinel_IsZero {
45         static bool check(Value v) { return v==0; }
46     };
47 }
48
49 BOOST_AUTO_UNIT_TEST(parse_ListS_simple)
50 {
51     unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x00 };
52     typedef unsigned char * iterator;
53     typedef Parse_ListS<Parse_UInt8<>,Sentinel_IsZero<unsigned char>,iterator> Parse_UInt8ListS;
54
55     Parse_UInt8ListS l (data);
56     Parse_UInt8ListS::iterator i (l.begin());
57     Parse_UInt8ListS::iterator e (l.end());
58     for (iterator c (data); *c; ++c) {
59         BOOST_REQUIRE( i!=e );
60         BOOST_CHECK_EQUAL( *c, *i );
61         ++i;
62     }
63     BOOST_CHECK( i==e );
64
65     BOOST_CHECK_EQUAL( l.bytes(), 5u );
66     BOOST_CHECK_EQUAL( l.size(), 4u );
67     BOOST_CHECK( !l.empty() );
68 }
69
70 namespace {
71     // LVec is a vector with the length living directly before the vector
72     template <class Parser, class SizeParser, class Iterator=nil, class IPacket=nil>
73     struct Parse_LVec
74         : public Parse_Vector<Parser, SizeParser,Iterator,IPacket>
75     {
76         template <class I=nil, class P=nil>
77         struct rebind { typedef Parse_LVec<Parser,SizeParser,I,P> parser; };
78         typedef typename SizeParser::template rebind<Iterator>::parser sizeParser;
79
80         Parse_LVec(Iterator const & i)
81             : Parse_Vector<Parser,SizeParser,Iterator,IPacket>(sizeParser(i),i+sizeParser::bytes())
82         {}
83
84         unsigned bytes() const
85         { return this->Parse_Vector<Parser,SizeParser,Iterator,IPacket>::bytes() + sizeParser::bytes(); }
86         bool check(Iterator const & e) const
87         // BEWARE .. this->i() points to the Vector not the SizeParser ... hrmpf ...
88         { return e>=this->i() && static_cast<unsigned>(e-this->i())+sizeParser::bytes() >= bytes(); }
89     };
90
91     template <class Array>
92     struct Sentinel_EmptyArray {
93         static bool check(Array a) { return a.empty(); }
94     };
95 }
96
97 BOOST_AUTO_UNIT_TEST(parse_ListS_complex)
98 {
99     unsigned char data[] = { 0x02, 0x01, 0x02,
100                              0x03, 0x11, 0x12, 0x13,
101                              0x04, 0x21, 0x22, 0x23, 0x24,
102                              0x00 };
103
104     typedef unsigned char * iterator;
105     typedef Parse_LVec<Parse_UInt8<>,Parse_UInt8<>,iterator> Parse_UInt8LVec;
106     typedef Parse_ListS<Parse_UInt8LVec,Sentinel_EmptyArray<Parse_UInt8LVec>,iterator> Parse_UInt8LVecListS;
107
108     Parse_UInt8LVecListS l (data);
109     BOOST_CHECK( l.check(data+13) );
110
111     Parse_UInt8LVecListS::iterator i (l.begin());
112     Parse_UInt8LVecListS::iterator e (l.end());
113     for (unsigned n (0); n<3; ++n) {
114         BOOST_REQUIRE( i!=e );
115         BOOST_CHECK_EQUAL( i->size(), n+2 );
116         Parse_UInt8LVec::iterator j (i->begin());
117         Parse_UInt8LVec::iterator je (i->end());
118         for (unsigned m (0); m<n+2; ++m, ++j) {
119             BOOST_CHECK( j!=je );
120             BOOST_CHECK_EQUAL( static_cast<unsigned>(*j), 16*n+m+1 );
121         }
122         BOOST_CHECK( j==je );
123         ++i;
124     }
125     BOOST_CHECK( i==e );
126
127     BOOST_CHECK_EQUAL( l.size(), 3u );
128     BOOST_CHECK_EQUAL( l.bytes(), 13u );
129     BOOST_CHECK( !l.empty() );
130 }
131
132 BOOST_AUTO_UNIT_TEST(parse_ListS_wrapper)
133 {
134     typedef std::vector<unsigned char> Container;
135     typedef Container::iterator iterator;
136     typedef Parse_LVec<Parse_UInt8<>,Parse_UInt8<>,iterator> Parse_UInt8LVec;
137     typedef Parse_ListS<Parse_UInt8LVec, Sentinel_EmptyArray<Parse_UInt8LVec>,iterator> Parse_UInt8LVecListS;
138     typedef Parse_UInt8LVecListS::wrapper<Container>::t Parse_UInt8LVecListSWrap;
139
140     using namespace boost::assign;
141
142     Container data;
143     data +=
144         0x02, 0x01, 0x02,
145         0x03, 0x11, 0x12, 0x13,
146         0x04, 0x21, 0x22, 0x23, 0x24,
147         0x00;
148
149     Parse_UInt8LVecListS l (data.begin());
150     Parse_UInt8LVecListSWrap w (l,data);
151
152     BOOST_CHECK_EQUAL( w.size(), 3u );
153     BOOST_CHECK ( !w.empty() );
154     BOOST_CHECK ( w.begin() != w.end() );
155     BOOST_CHECK ( w.range() == std::make_pair(w.begin(), w.end()) );
156
157 #if 0
158     unsigned char newdata[] = { 0x01, 0x00 };
159
160     w.insert(w.begin(),Parse_UInt8LVec::rebind<unsigned char*>::parser(newdata));
161     BOOST_CHECK_EQUAL( w.size(), 4u );
162     BOOST_CHECK_EQUAL( w.begin()->size(), 1u );
163     BOOST_CHECK_EQUAL( static_cast<unsigned>((*w.begin())[0]), 0x00u );
164 #endif
165 }
166
167 ///////////////////////////////cc.e////////////////////////////////////////
168 #undef prefix_
169
170 \f
171 // Local Variables:
172 // mode: c++
173 // fill-column: 100
174 // c-file-style: "senf"
175 // indent-tabs-mode: nil
176 // ispell-local-dictionary: "american"
177 // End: