f79d84b5833289527c3d4b3d0634175789ad30f0
[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     safe_data_iterator si (data(), i());
167     if (current_size > size)
168         data().erase( si, boost::next(si, current_size-size));
169     else
170         data().insert( si, size-current_size, 0);
171     
172     if (size > 1) {
173         safeThis->extended_length_flag() = true;
174         safeThis->fixed_length_field() = size - 1;
175     } else {
176         safeThis->extended_length_flag() = false;
177     }
178     value(v);
179 }
180
181
182 prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os)
183 {
184     boost::io::ios_all_saver ias(os);
185     os << "GenericTLVPacket:\n"
186        << std::dec
187        << "  type:   " << unsigned( p->type()) << "\n"
188        << "  length: " << unsigned( p->length()) << "\n"
189        << "  value\n:";
190     senf::hexdump( p->value().begin(), p->value().end(), os);
191 }
192
193
194 prefix_ void senf::GenericTLVPacketType::finalize(packet p)
195 {
196     p->shrinkLength();
197 }
198
199
200 ///////////////////////////////cc.e////////////////////////////////////////
201 #undef prefix_
202
203 \f
204 // Local Variables:
205 // mode: c++
206 // fill-column: 100
207 // c-file-style: "senf"
208 // indent-tabs-mode: nil
209 // ispell-local-dictionary: "american"
210 // compile-command: "scons -u test"
211 // comment-column: 40
212 // End: