8184317b55dbceefd839631076fd5b3276ba154b
[senf.git] / senf / Packets / Packet.cti
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 //     Stefan Bund <g0dil@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 Packet inline template implementation */
25
26 //#include "Packet.ih"
27
28 // Custom includes
29 #include <senf/Utils/Exception.hh>
30
31 #define prefix_ inline
32 //-/////////////////////////////////////////////////////////////////////////////////////////////////
33
34 //-/////////////////////////////////////////////////////////////////////////////////////////////////
35 // senf::Packet
36
37 // conversion constructors
38
39 template <class PacketType>
40 prefix_ senf::Packet::Packet(ConcretePacket<PacketType> const & packet)
41     : packet_(packet.ptr())
42 {}
43
44 // interpreter chain access
45
46 template <class OtherPacket>
47 prefix_ OtherPacket senf::Packet::parseNextAs()
48     const
49 {
50     return OtherPacket(ptr()->parseNextAs<typename OtherPacket::type>());
51 }
52
53 template <class OtherPacket>
54 prefix_ bool senf::Packet::is()
55     const
56 {
57     return valid() && ptr()->is<typename OtherPacket::type>();
58 }
59
60 template <class OtherPacket>
61 prefix_ OtherPacket senf::Packet::as()
62     const
63 {
64     if (!is<OtherPacket>())
65         throw WrapException<std::bad_cast>(std::bad_cast())
66             << ": called packet::as() with wrong PacketType: "
67             << (valid() ? typeId().prettyName() : "invalid packet")
68             << " != " << prettyName(typeid(OtherPacket));
69     return OtherPacket(ptr()->as<typename OtherPacket::type>());
70 }
71
72 template <class OtherPacket>
73 prefix_ OtherPacket senf::Packet::as(NoThrow_t)
74     const
75 {
76     SENF_ASSERT( is<OtherPacket>(), "Bad cast, called packet::as(nothrow) with wrong PacketType");
77     return OtherPacket(ptr()->as<typename OtherPacket::type>());
78 }
79
80 template <class OtherPacket>
81 prefix_ OtherPacket senf::Packet::next()
82     const
83 {
84     return next().as<OtherPacket>();
85 }
86
87 template <class OtherPacket>
88 prefix_ OtherPacket senf::Packet::next(NoThrow_t)
89     const
90 {
91     Packet p (next(nothrow));
92     return p && p.is<OtherPacket>() ?
93             OtherPacket(p.ptr()->as<typename OtherPacket::type>()) : OtherPacket();
94 }
95
96 template <class OtherPacket>
97 prefix_ OtherPacket senf::Packet::find()
98     const
99 {
100     OtherPacket p (find<OtherPacket>(nothrow));
101     if (!p) throw InvalidPacketChainException();
102     return p;
103 }
104
105 template <class OtherPacket>
106 prefix_ OtherPacket senf::Packet::prev()
107     const
108 {
109     return prev().as<OtherPacket>();
110 }
111
112 template <class OtherPacket>
113 prefix_ OtherPacket senf::Packet::prev(NoThrow_t)
114     const
115 {
116     Packet p (prev(nothrow));
117     return p && p.is<OtherPacket>() ?
118             OtherPacket(p.ptr()->as<typename OtherPacket::type>()) : OtherPacket();
119 }
120
121 template <class OtherPacket>
122 prefix_ OtherPacket senf::Packet::rfind()
123     const
124 {
125     OtherPacket p (rfind<OtherPacket>(nothrow));
126     if (!p) throw InvalidPacketChainException();
127     return p;
128 }
129
130 template <class OtherPacket>
131 prefix_ OtherPacket senf::Packet::last()
132     const
133 {
134     return last().as<OtherPacket>();
135 }
136
137 template <class OtherPacket>
138 prefix_ OtherPacket senf::Packet::first()
139     const
140 {
141     return first().as<OtherPacket>();
142 }
143
144 template <class Other>
145 prefix_ void senf::Packet::finalizeTo()
146 {
147     Packet p (find<Other>(nothrow));
148     ptr()->finalizeTo(p ? p.ptr() : last().ptr());
149 }
150
151 template <class Annotation>
152 prefix_ Annotation & senf::Packet::annotation()
153 {
154     return ptr()->annotation<Annotation>();
155 }
156
157 template <class Annotation>
158 prefix_ Annotation const & senf::Packet::annotation()
159     const
160 {
161     return ptr()->annotation<Annotation>();
162 }
163
164 //-/////////////////////////////////////////////////////////////////////////////////////////////////
165 // senf::ConcretePacket<PacketType>
166
167 // structors and default members
168
169 template <class PacketType>
170 prefix_ senf::ConcretePacket<PacketType>::ConcretePacket()
171 {}
172
173 template <class PacketType>
174 prefix_ typename senf::ConcretePacket<PacketType>::factory_t
175 senf::ConcretePacket<PacketType>::factory()
176 {
177     return interpreter::factory();
178 }
179
180 // Create completely new packet
181
182 template <class PacketType>
183 prefix_ senf::ConcretePacket<PacketType>
184 senf::ConcretePacket<PacketType>::create()
185 {
186     return ConcretePacket(interpreter::create());
187 }
188
189 template <class PacketType>
190 prefix_ senf::ConcretePacket<PacketType>
191 senf::ConcretePacket<PacketType>::create(senf::NoInit_t)
192 {
193     return ConcretePacket(interpreter::create(senf::noinit));
194 }
195
196 template <class PacketType>
197 prefix_ senf::ConcretePacket<PacketType>
198 senf::ConcretePacket<PacketType>::create(size_type size)
199 {
200     return ConcretePacket(interpreter::create(size));
201 }
202
203 template <class PacketType>
204 prefix_ senf::ConcretePacket<PacketType>
205 senf::ConcretePacket<PacketType>::create(size_type size, senf::NoInit_t)
206 {
207     return ConcretePacket(interpreter::create(size,senf::noinit));
208 }
209
210 #ifndef DOXYGEN
211
212 template <class PacketType>
213 template <class ForwardReadableRange>
214 prefix_ senf::ConcretePacket<PacketType> senf::ConcretePacket<PacketType>::
215 create(ForwardReadableRange const & range,
216        typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type *)
217 {
218     return ConcretePacket(interpreter::create(range));
219 }
220
221 #endif
222
223 // Create packet as new packet after a given packet
224
225 template <class PacketType>
226 prefix_ senf::ConcretePacket<PacketType>
227 senf::ConcretePacket<PacketType>::createAfter(Packet const & packet)
228 {
229     return ConcretePacket(interpreter::createAfter(packet.ptr()));
230 }
231
232 template <class PacketType>
233 prefix_ senf::ConcretePacket<PacketType>
234 senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, senf::NoInit_t)
235 {
236     return ConcretePacket(interpreter::createAfter(packet.ptr(),senf::noinit));
237 }
238
239 template <class PacketType>
240 prefix_ senf::ConcretePacket<PacketType>
241 senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, size_type size)
242 {
243     return ConcretePacket(interpreter::createAfter(packet.ptr(), size));
244 }
245
246 template <class PacketType>
247 prefix_ senf::ConcretePacket<PacketType>
248 senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, size_type size,
249                                               senf::NoInit_t)
250 {
251     return ConcretePacket(interpreter::createAfter(packet.ptr(), size, senf::noinit));
252 }
253
254 #ifndef DOXYGEN
255
256 template <class PacketType>
257 template <class ForwardReadableRange>
258 prefix_ senf::ConcretePacket<PacketType> senf::ConcretePacket<PacketType>::
259 createAfter(Packet const & packet, ForwardReadableRange const & range,
260             typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type *)
261 {
262     return ConcretePacket(interpreter::createAfter(packet.ptr(), range));
263 }
264
265 #endif
266
267 // Create packet as new packet (header) before a given packet
268
269 template <class PacketType>
270 prefix_ senf::ConcretePacket<PacketType>
271 senf::ConcretePacket<PacketType>::createBefore(Packet const & packet)
272 {
273     return ConcretePacket(interpreter::createBefore(packet.ptr()));
274 }
275
276 template <class PacketType>
277 prefix_ senf::ConcretePacket<PacketType>
278 senf::ConcretePacket<PacketType>::createBefore(Packet const & packet, senf::NoInit_t)
279 {
280     return ConcretePacket(interpreter::createBefore(packet.ptr(), senf::noinit));
281 }
282
283 template <class PacketType>
284 prefix_ senf::ConcretePacket<PacketType>
285 senf::ConcretePacket<PacketType>::createInsertBefore(Packet const & packet)
286 {
287     return ConcretePacket(interpreter::createInsertBefore(packet.ptr()));
288 }
289
290 template <class PacketType>
291 prefix_ senf::ConcretePacket<PacketType>
292 senf::ConcretePacket<PacketType>::createInsertBefore(Packet const & packet, senf::NoInit_t)
293 {
294     return ConcretePacket(interpreter::createInsertBefore(packet.ptr(), senf::noinit));
295 }
296
297 // Create a clone of the current packet
298
299 template <class PacketType>
300 prefix_ senf::ConcretePacket<PacketType>
301 senf::ConcretePacket<PacketType>::clone()
302     const
303 {
304     return ConcretePacket(ptr()->clone());
305 }
306
307 // Field access
308
309 template <class PacketType>
310 prefix_ typename senf::ConcretePacket<PacketType>::Parser
311 senf::ConcretePacket<PacketType>::parser()
312     const
313 {
314     return ptr()->fields();
315 }
316
317 template <class PacketType>
318 prefix_ typename senf::ConcretePacket<PacketType>::ParserProxy
319 senf::ConcretePacket<PacketType>::operator->()
320     const
321 {
322     return ParserProxy(parser());
323 }
324
325 // private members
326
327 template <class PacketType>
328 prefix_ senf::ConcretePacket<PacketType>::ConcretePacket(typename interpreter::ptr const & packet_)
329     : Packet(packet_)
330 {}
331
332 template <class PacketType>
333 prefix_ typename senf::ConcretePacket<PacketType>::interpreter * senf::ConcretePacket<PacketType>::ptr()
334     const
335 {
336     return static_cast< PacketInterpreter<PacketType> *>( Packet::ptr().get());
337 }
338
339 //-/////////////////////////////////////////////////////////////////////////////////////////////////
340 #undef prefix_
341
342 \f
343 // Local Variables:
344 // mode: c++
345 // fill-column: 100
346 // c-file-style: "senf"
347 // indent-tabs-mode: nil
348 // ispell-local-dictionary: "american"
349 // compile-command: "scons -u test"
350 // comment-column: 40
351 // End: