GenericTLVPacketParser: fix for 64bit
[senf.git] / Packets / 80221Bundle / TLVPacket.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Thorsten Horstmann <tho@berlios.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 /** \file
24     \brief TLVPacket non-inline non-template implementation */
25
26 #include "TLVPacket.hh"
27 //#include "TLVPacket.ih"
28
29 // Custom includes
30 #include <iomanip>
31 #include <senf/Utils/hexdump.hh>
32
33 #define prefix_
34 ///////////////////////////////cc.p////////////////////////////////////////
35
36 prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::value() const 
37 {
38     switch (bytes() ) {
39     case 1:
40         return fixed_length_field().value();
41     case 2:
42         return parse<UInt8Parser>( 1 ).value();
43     case 3:
44         return parse<UInt16Parser>( 1 ).value();
45     case 4:
46         return parse<UInt24Parser>( 1 ).value();
47     case 5:
48         return parse<UInt32Parser>( 1 ).value();
49     default:
50         throw(TLVLengthException());
51     };
52 }
53
54
55 prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v) 
56 {
57     switch (bytes() ) {
58     case 1:
59         if (v > 127) throw( TLVLengthException());
60         fixed_length_field() = v;
61         return;
62     case 2:
63         if (v > UInt8Parser::max_value) throw( TLVLengthException());
64         parse<UInt8Parser>(1) = v;
65         return;
66     case 3:
67         if (v > UInt16Parser::max_value) throw( TLVLengthException());
68         parse<UInt16Parser>(1) = v;
69         return;
70     case 4:
71         if (v > UInt24Parser::max_value) throw( TLVLengthException());
72         parse<UInt24Parser>(1) = v;
73         return;
74     case 5:
75         parse<UInt32Parser>(1) = v;
76         return;
77     default:
78         throw( TLVLengthException());
79     };
80 }
81
82
83 prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::operator= (value_type other) 
84 {
85     value(other);
86     return *this; 
87 }
88
89
90 prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const 
91 {
92     if ( extended_length_flag() )
93         return 1 + fixed_length_field();
94     else
95         return 1;
96 }
97     
98
99 prefix_ void senf::DynamicTLVLengthParser::init() const 
100 {
101     defaultInit();
102     extended_length_flag() = false;
103 }
104
105
106 prefix_ void senf::DynamicTLVLengthParser::shrink()
107 {
108     value_type v = value();
109     size_type b = bytes();
110     if (v <= 127) {
111         if (b != 1) resize(1);
112         return;
113     }
114     if (v <= UInt8Parser::max_value) {
115         if (b != 2) resize(2);
116         return;
117     }
118     if (v <= UInt16Parser::max_value) {
119         if (b != 3) resize(3);
120         return;
121     }
122     if (v <= UInt24Parser::max_value) {
123         if (b != 4) resize(4);
124         return;
125     }
126     if (b != 5) resize(5);
127 }
128
129
130 prefix_ void senf::DynamicTLVLengthParser:: maxValue(DynamicTLVLengthParser::value_type v)
131 {
132     if (v <= 127)
133         return;
134     size_type b = bytes();
135     if (v <= UInt8Parser::max_value) {
136         if (b < 2) resize(2);
137         return;
138     }
139     if (v <= UInt16Parser::max_value) {
140         if (b < 3) resize(3);
141         return;
142     }
143     if (v <= UInt24Parser::max_value) {
144         if (b < 4) resize(4);
145         return;
146     }
147     if (b < 5) resize(5);
148 }
149
150
151 prefix_ senf::PacketInterpreterBase::range senf::GenericTLVPacketParser::value() 
152     const
153 {
154     senf::PacketData::iterator begin (boost::next(data().begin(), 1 + length_bytes() ));
155     return PacketInterpreterBase::range(
156             begin, boost::next( begin, length()) );
157 }
158
159
160 prefix_ void senf::DynamicTLVLengthParser::resize(size_type size)
161 {
162     value_type v = value();
163     size_type current_size (bytes());
164     SafePacketParserWrapper<DynamicTLVLengthParser> safeThis (*this);
165     
166     if (current_size > size)
167         data().erase( i(), boost::next(i(), current_size-size));
168     else
169         data().insert( i(), size-current_size, 0);
170     
171     if (size > 1) {
172         safeThis->extended_length_flag() = true;
173         safeThis->fixed_length_field() = size - 1;
174     } else {
175         safeThis->extended_length_flag() = false;
176     }
177     safeThis->value(v);
178 }
179
180
181 prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os)
182 {
183     boost::io::ios_all_saver ias(os);
184     os << "GenericTLVPacket:\n"
185        << std::dec
186        << "  type:   " << unsigned( p->type()) << "\n"
187        << "  length: " << unsigned( p->length()) << "\n"
188        << "  value\n:";
189     senf::hexdump( p->value().begin(), p->value().end(), os);
190 }
191
192
193 prefix_ void senf::GenericTLVPacketType::finalize(packet p)
194 {
195     p->shrinkLength();
196 }
197
198
199 ///////////////////////////////cc.e////////////////////////////////////////
200 #undef prefix_
201
202 \f
203 // Local Variables:
204 // mode: c++
205 // fill-column: 100
206 // c-file-style: "senf"
207 // indent-tabs-mode: nil
208 // ispell-local-dictionary: "american"
209 // compile-command: "scons -u test"
210 // comment-column: 40
211 // End: