more work on TLV & MIH Packet
[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(UnsuportedTLVPacketException());
51     };
52 }
53
54 prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v) 
55 {
56     SafePacketParserWrapper<DynamicTLVLengthParser> safeThis (*this);
57     if (v < 128u) {
58         if (bytes() != 1)
59             resize(1, safeThis);
60         safeThis->fixed_length_field() = v;
61         return;
62     }
63     if (v <= UInt8Parser::max_value) {
64         if (bytes() != 2)
65             resize(2, safeThis);
66         safeThis->parse<UInt8Parser>(1) = v;
67         return;
68     }
69     if (v <= UInt16Parser::max_value) {
70         if (bytes() != 3)
71             resize(3, safeThis);
72         safeThis->parse<UInt16Parser>(1) = v;
73         return;
74     }
75     if (v <= UInt24Parser::max_value) {
76         if (bytes() != 4)
77             resize(4, safeThis);
78         safeThis->parse<UInt24Parser>(1) = v;
79         return;
80     }
81     if (v <= UInt32Parser::max_value) {
82         if (bytes() != 5)
83             resize(5, safeThis);
84         safeThis->parse<UInt32Parser>(1) = v;
85         return;
86     }
87     throw(UnsuportedTLVPacketException());
88 }
89
90 prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::operator= (value_type other) 
91 {
92     value(other);
93     return *this; 
94 }
95
96 prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const 
97 {
98     if ( extended_length_flag() )
99         return 1 + fixed_length_field();
100     else
101         return 1;
102 }
103     
104 prefix_ void senf::DynamicTLVLengthParser::init() const 
105 {
106     defaultInit();
107     extended_length_flag() = 0;
108 }
109
110 prefix_ void senf::DynamicTLVLengthParser::resize(
111         size_type size, SafePacketParserWrapper<DynamicTLVLengthParser> &safeThis) 
112 {
113     std::cout << "DynamicTLVLengthParser::resize " << unsigned( size) << "\n";
114     if (size > 1) {
115         safeThis->extended_length_flag() = true;
116         safeThis->fixed_length_field() = size - 1;
117     } else {
118         safeThis->extended_length_flag() = false;
119     }
120     
121     size_type current_size (bytes());
122     safe_data_iterator si (data(), i());
123     
124     if (current_size > size)
125         data().erase( si, boost::next(si, current_size-size));
126     else
127         data().insert( si, size-current_size, 0);
128 }
129
130 prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os)
131 {
132     boost::io::ios_all_saver ias(os);
133     os << "GenericTLVPacket:\n"
134        << std::dec
135        << "  type:   " << unsigned( p->type()) << "\n"
136        << "  length: " << unsigned( p->length()) << "\n";
137 }
138
139 //prefix_ void senf::GenericTLVPacketType::finalize(packet p)
140 //{
141 //    try {
142 //        PacketData::size_type size = p.next().data().size();
143 //        if ( size > DynamicTLVLengthParser::max_value )
144 //            throw(UnsuportedTLVPacketException());
145 //        p->length() = size;
146 //    }
147 //    catch (InvalidPacketChainException & ex) {
148 //        ;
149 //    }
150 //}
151
152
153 //template <class TypeParser, class LengthParser>
154 //prefix_ senf::PacketInterpreterBase::optional_range 
155 //senf::TLVPacketType<TypeParser, LengthParser>::nextPacketRange(packet p) 
156 //{
157 //    if (p.data().size() < 5)
158 //        return no_range();
159 //    return range(
160 //            boost::next(p.data().begin(), 4 + senf::bytes(p->length()) ),
161 //            p.data().end() );
162 //}
163
164
165 ///////////////////////////////cc.e////////////////////////////////////////
166 #undef prefix_
167
168 \f
169 // Local Variables:
170 // mode: c++
171 // fill-column: 100
172 // c-file-style: "senf"
173 // indent-tabs-mode: nil
174 // ispell-local-dictionary: "american"
175 // compile-command: "scons -u test"
176 // comment-column: 40
177 // End: