TLVPacket creating with changing HeaderSize doesn't work :(
[senf.git] / Packets / MPEGDVBBundle / TLVPacket.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Thorsten Horstmann <thorsten.horstmann@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 /** \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::Parse_TLVPacketLength::value_type senf::Parse_TLVPacketLength::value() const {
37     switch (bytes() ) {
38     case 1:
39         return fixed_length_field().value();
40     case 2:
41         return parse<Parse_UInt8>( 1 ).value();
42     case 3:
43         return parse<Parse_UInt16>( 1 ).value();
44     case 4:
45         return parse<Parse_UInt24>( 1 ).value();
46     case 5:
47         return parse<Parse_UInt32>( 1 ).value();
48     default:
49         throw(UnsuportedTLVPacketException());
50     };
51 }
52
53 prefix_ void senf::Parse_TLVPacketLength::value(value_type const & v) {
54     if (v > 4294967295u)
55         throw(UnsuportedTLVPacketException());
56         
57     if (v < 128u) {
58         if (bytes() != 1) resize(1);
59         fixed_length_field() = v;
60         return;
61     }
62     if (v < 256u) {
63         if (bytes() != 2) resize(2);
64         parse<Parse_UInt8>(1) = v;
65         return;
66     }
67     if (v < 65536u) {
68         if (bytes() != 3) resize(3);
69         parse<Parse_UInt16>(1) = v;
70         return;
71     }
72     if (v < 16777216u) {
73         if (bytes() != 4) resize(4);
74         parse<Parse_UInt24>(1) = v;
75         return;
76     }
77     if (v <= 4294967295u) {
78         if (bytes() != 5) resize(5);
79         parse<Parse_UInt32>(1) = v;
80         return;
81     }
82 }
83
84 prefix_ senf::Parse_TLVPacketLength const & senf::Parse_TLVPacketLength::operator= (value_type other) {
85     value(other);
86     return *this; 
87 }
88
89 prefix_ senf::Parse_TLVPacketLength::size_type senf::Parse_TLVPacketLength::bytes() const {
90     if ( extended_length_flag() )
91         return 1 + fixed_length_field();
92     else
93         return 1;
94 }
95     
96 prefix_ void senf::Parse_TLVPacketLength::init() const {
97     defaultInit();
98     extended_length_flag() = 0;
99 }
100
101 prefix_ void senf::Parse_TLVPacketLength::resize(size_type size) {
102     std::cout << "senf::Parse_TLVPacketLength::resize: " << unsigned(size) << "\n";
103 //    hexdump(data().begin(), data().end(), std::cout);
104     
105     size_type current_size (bytes());
106     safe_data_iterator si (data(), i());
107     
108     if (current_size > size)
109         data().erase( si, boost::next(si, current_size-size));
110     else {
111         data().insert( si, size-current_size, 0);
112         Parse_TLVPacketLength(si,state()).init();
113     }
114     
115     if (size > 1) {
116         extended_length_flag() = 1;
117         fixed_length_field() = size-1;
118     } else {
119         extended_length_flag() = 0;
120     }
121     
122 //    hexdump(data().begin(), data().end(), std::cout);
123 }
124
125
126 prefix_ void senf::TLVPacketType::dump(packet p, std::ostream & os)
127 {
128     os << "TLVPacket:\n"
129        << std::dec
130        << "  type: " <<  unsigned(p->type()) << "\n"
131        << "  length: " << unsigned(p->length()) << "\n";
132 }
133
134 prefix_ senf::PacketParserBase::size_type senf::TLVPacketType::initSize()
135 {
136     return 5;  // 4 bytes type + 1 byte length
137 }
138
139 prefix_ void senf::TLVPacketType::init(packet p)
140 {
141     p->init();
142 }
143
144 prefix_ void senf::TLVPacketType::finalize(packet p)
145 {
146     p->length() = p.next().data().size();
147 }
148
149 prefix_ senf::PacketInterpreterBase::optional_range 
150 senf::TLVPacketType::nextPacketRange(packet p) 
151 {
152     if (p.data().size() < 5)
153         return no_range();
154     return range(
155             boost::next(p.data().begin(), 4 + senf::bytes(p->length()) ),
156             p.data().end() );
157 }
158
159
160 ///////////////////////////////cc.e////////////////////////////////////////
161 #undef prefix_
162
163 \f
164 // Local Variables:
165 // mode: c++
166 // fill-column: 100
167 // c-file-style: "senf"
168 // indent-tabs-mode: nil
169 // ispell-local-dictionary: "american"
170 // compile-command: "scons -u test"
171 // comment-column: 40
172 // End: