Packets/80221Bundle: integrated GenericTLVRegistry
[senf.git] / senf / Packets / 80221Bundle / TLVParser.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 TLVParser non-inline non-template implementation */
25
26 #include "TLVParser.hh"
27 //#include "TLVParser.ih"
28
29 // Custom includes
30 #include <iomanip>
31 #include <senf/Utils/hexdump.hh>
32
33 #define prefix_
34 ///////////////////////////////cc.p////////////////////////////////////////
35
36 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFSrcIdTLVParser );
37 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFDstIdTLVParser );
38
39 ///////////////////////////////////////////////////////////////////////////
40 // senf::MIHFIdTLVParser
41
42 prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
43     const
44 {
45     os << senf::fieldName("  type")   << unsigned (type())   << "\n"
46        << senf::fieldName("  length") << unsigned (length()) << "\n"
47        << "    value:\n";
48     std::string src_mihfId (asString());
49     hexdump(src_mihfId.begin(), src_mihfId.end(), os);
50 }
51
52 prefix_ void senf::MIHFIdTLVParser::setString(std::string const &id)
53 {
54     size_type str_size (id.size());
55     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
56     if (str_size > 253) 
57         throw std::length_error("maximum length of a MIHF_ID is 253 octets");
58     safe_data_iterator si = resizeValueField( str_size);   
59     std::copy( id.begin(), id.end(), si);
60 }
61
62 prefix_ void senf::MIHFIdTLVParser::setMACAddress(senf::MACAddress const &mac)
63 {
64     safe_data_iterator si = resizeValueField(12);
65     std::copy( mac.begin(), mac.end(), getNAIEncodedOutputIterator(si));
66 }
67
68 prefix_ void senf::MIHFIdTLVParser::setINet4Address(senf::INet4Address const &addr)
69 {
70     safe_data_iterator si = resizeValueField(8);
71     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
72 }
73
74 prefix_ void senf::MIHFIdTLVParser::setINet6Address(senf::INet6Address const &addr)
75 {
76     safe_data_iterator si = resizeValueField(32);
77     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
78 }
79
80 prefix_ void senf::MIHFIdTLVParser::setEUI64(senf::EUI64 const &addr)
81 {
82     safe_data_iterator si = resizeValueField(16);
83     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
84 }
85
86 prefix_ senf::MIHFId senf::MIHFIdTLVParser::valueAs(MIHFId::Type type)
87     const
88 {
89     if (length() == 0) return MIHFId();
90     switch (type) {
91     case MIHFId::Empty:
92         return MIHFId();
93     case MIHFId::MACAddress:
94         return MIHFId( asMACAddress());
95     case MIHFId::INet4Address:
96         return MIHFId( asINet4Address());
97     case MIHFId::INet6Address:
98         return MIHFId( asINet6Address());
99     case MIHFId::String:
100         return MIHFId( asINet6Address());
101     case MIHFId::EUI64:
102         return MIHFId( asINet6Address());
103     }
104     return MIHFId();
105 }
106
107
108 ///////////////////////////////////////////////////////////////////////////
109 // senf::MIHFSrcIdTLVParser
110
111 prefix_ void senf::MIHFSrcIdTLVParser::dump(std::ostream & os)
112     const
113 {
114     os << "  source MIHF_Id TLV:\n";
115     MIHFIdTLVParser::dump(os);
116 }
117
118 ///////////////////////////////////////////////////////////////////////////
119 // senf::MIHFDstIdTLVParser
120
121 prefix_ void senf::MIHFDstIdTLVParser::dump(std::ostream & os)
122     const
123 {
124     os << "  destination MIHF_Id TLV:\n";
125     MIHFIdTLVParser::dump(os);
126 }
127
128 ///////////////////////////////////////////////////////////////////////////
129 // MIHBaseTLVParser
130
131 prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
132         MIHTLVLengthParser::value_type size) 
133 {
134     MIHTLVLengthParser::value_type current_length ( length());
135     length_() << size;
136
137     safe_data_iterator si (data(), boost::next(i(), 1 + length_().bytes() ));
138     if (current_length > size)
139         data().erase( si, boost::next(si, current_length-size));
140     else
141         data().insert( si, size-current_length, 0);
142     return si;
143 }
144
145
146 ///////////////////////////////////////////////////////////////////////////
147 // senf::MIHTLVLengthParser
148
149 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const 
150 {
151     switch (bytes() ) {
152     case 1:
153         return length_field().value();
154     case 2:
155         return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
156     case 3:
157         return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
158     case 4:
159         return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
160     case 5:
161         return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
162     default:
163         throw( MIHTLVLengthException());
164     };
165 }
166
167 prefix_ void senf::MIHTLVLengthParser::value(value_type const & v) 
168 {
169     switch (bytes() ) {
170     case 1:
171         if (v > 128) throw( MIHTLVLengthException());
172         length_field() = v;
173         return;
174     case 2:
175         if (v > UInt8Parser::max_value + 128) throw( MIHTLVLengthException());
176         parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
177         break;
178     case 3:
179         if (v > UInt16Parser::max_value + 128) throw( MIHTLVLengthException());
180         parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
181         break;;
182     case 4:
183         if (v > UInt24Parser::max_value + 128) throw( MIHTLVLengthException());
184         parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
185         break;
186     case 5:
187         parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
188         break;
189     default:
190         throw( MIHTLVLengthException());
191     };
192     underflow_flag() = (v <= 128);
193 }
194
195 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue()
196     const
197 {
198     switch (bytes() ) {
199     case 1:
200         return 128;
201     case 2:
202         return UInt8Parser::max_value + 128;
203     case 3:
204         return UInt16Parser::max_value + 128;
205     case 4:
206         return UInt24Parser::max_value + 128;
207     case 5:
208         return UInt32Parser::max_value; 
209     default:
210         throw( MIHTLVLengthException());
211     };
212 }
213
214 prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other) 
215 {
216     value(other);
217     return *this; 
218 }
219
220 prefix_ void senf::MIHTLVLengthParser::init() const 
221 {
222     defaultInit();
223     extended_length_flag() = false;
224 }
225
226 prefix_ void senf::MIHTLVLengthParser::finalize()
227 {
228     value_type v = value();
229     size_type b = bytes();
230     if (v <= 128) {
231         if (b != 1) resize_(1);
232         return;
233     }
234     if (v <= UInt8Parser::max_value + 128) {
235         if (b != 2) resize_(2);
236         return;
237     }
238     if (v <= UInt16Parser::max_value + 128) {
239         if (b != 3) resize_(3);
240         return;
241     }
242     if (v <= UInt24Parser::max_value + 128 ) {
243         if (b != 4) resize_(4);
244         return;
245     }
246     if (b != 5) resize_(5);
247 }
248
249 prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type v)
250 {
251     if (v <= 128)
252         return;
253     size_type b = bytes();
254     if (v <= UInt8Parser::max_value + 128) {
255         if (b < 2) resize_(2);
256         return;
257     }
258     if (v <= UInt16Parser::max_value + 128) {
259         if (b < 3) resize_(3);
260         return;
261     }
262     if (v <= UInt24Parser::max_value + 128) {
263         if (b < 4) resize_(4);
264         return;
265     }
266     if (b < 5) resize_(5);
267 }
268
269 prefix_ void senf::MIHTLVLengthParser::resize_(size_type size)
270 {
271     value_type v = value();
272     resize(bytes(), size);
273     if (size > 1) {
274         extended_length_flag() = true;
275         fixed_length_field() = size - 1;
276     } else {
277         extended_length_flag() = false;
278     }
279     value(v);
280 }
281
282
283 ///////////////////////////////cc.e////////////////////////////////////////
284 #undef prefix_
285
286 \f
287 // Local Variables:
288 // mode: c++
289 // fill-column: 100
290 // c-file-style: "senf"
291 // indent-tabs-mode: nil
292 // ispell-local-dictionary: "american"
293 // compile-command: "scons -u test"
294 // comment-column: 40
295 // End: