Packets: not really a smart but efficient 'shortcut' for ConcretePacket::next() ...
[senf.git] / senf / Packets / Packet.cti
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Packet inline template implementation */
30
31 //#include "Packet.ih"
32
33 // Custom includes
34 #include <senf/Utils/Exception.hh>
35
36 #define prefix_ inline
37 //-/////////////////////////////////////////////////////////////////////////////////////////////////
38
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40 // senf::Packet
41
42 // conversion constructors
43
44 template <class PacketType>
45 prefix_ senf::Packet::Packet(ConcretePacket<PacketType> const & packet)
46     : packet_(packet.ptr())
47 {}
48
49 // interpreter chain access
50
51 template <class OtherPacket>
52 prefix_ OtherPacket senf::Packet::parseNextAs()
53     const
54 {
55     return OtherPacket(ptr()->parseNextAs<typename OtherPacket::type>());
56 }
57
58 template <class OtherPacket>
59 prefix_ bool senf::Packet::is()
60     const
61 {
62     return valid() && ptr()->is<typename OtherPacket::type>();
63 }
64
65 template <class OtherPacket>
66 prefix_ OtherPacket senf::Packet::as()
67     const
68 {
69     if (!is<OtherPacket>())
70         throw WrapException<std::bad_cast>(std::bad_cast())
71             << ": called packet::as() with wrong PacketType: "
72             << (valid() ? typeId().prettyName() : "invalid packet")
73             << " != " << prettyName(typeid(OtherPacket));
74     return OtherPacket(ptr()->as<typename OtherPacket::type>());
75 }
76
77 template <class OtherPacket>
78 prefix_ OtherPacket senf::Packet::as(NoThrow_t)
79     const
80 {
81     SENF_ASSERT( is<OtherPacket>(), "Bad cast, called packet::as(nothrow) with wrong PacketType");
82     return OtherPacket(ptr()->as<typename OtherPacket::type>());
83 }
84
85 template <class OtherPacket>
86 prefix_ OtherPacket senf::Packet::next()
87     const
88 {
89     return next().as<OtherPacket>();
90 }
91
92 template <class OtherPacket>
93 prefix_ OtherPacket senf::Packet::next(NoThrow_t)
94     const
95 {
96     Packet p (next(nothrow));
97     return p && p.is<OtherPacket>() ?
98             OtherPacket(p.ptr()->as<typename OtherPacket::type>()) : OtherPacket();
99 }
100
101 template <class OtherPacket>
102 prefix_ OtherPacket senf::Packet::find()
103     const
104 {
105     OtherPacket p (find<OtherPacket>(nothrow));
106     if (!p) throw InvalidPacketChainException();
107     return p;
108 }
109
110 template <class OtherPacket>
111 prefix_ OtherPacket senf::Packet::prev()
112     const
113 {
114     return prev().as<OtherPacket>();
115 }
116
117 template <class OtherPacket>
118 prefix_ OtherPacket senf::Packet::prev(NoThrow_t)
119     const
120 {
121     Packet p (prev(nothrow));
122     return p && p.is<OtherPacket>() ?
123             OtherPacket(p.ptr()->as<typename OtherPacket::type>()) : OtherPacket();
124 }
125
126 template <class OtherPacket>
127 prefix_ OtherPacket senf::Packet::rfind()
128     const
129 {
130     OtherPacket p (rfind<OtherPacket>(nothrow));
131     if (!p) throw InvalidPacketChainException();
132     return p;
133 }
134
135 template <class OtherPacket>
136 prefix_ OtherPacket senf::Packet::last()
137     const
138 {
139     return last().as<OtherPacket>();
140 }
141
142 template <class OtherPacket>
143 prefix_ OtherPacket senf::Packet::first()
144     const
145 {
146     return first().as<OtherPacket>();
147 }
148
149 template <class Other>
150 prefix_ void senf::Packet::finalizeTo()
151 {
152     Packet p (find<Other>(nothrow));
153     ptr()->finalizeTo(p ? p.ptr() : last().ptr());
154 }
155
156 template <class Annotation>
157 prefix_ Annotation & senf::Packet::annotation()
158 {
159     return ptr()->annotation<Annotation>();
160 }
161
162 template <class Annotation>
163 prefix_ Annotation const & senf::Packet::annotation()
164     const
165 {
166     return ptr()->annotation<Annotation>();
167 }
168
169 //-/////////////////////////////////////////////////////////////////////////////////////////////////
170 // senf::ConcretePacket<PacketType>
171
172 // structors and default members
173
174 template <class PacketType>
175 prefix_ senf::ConcretePacket<PacketType>::ConcretePacket()
176 {}
177
178 template <class PacketType>
179 prefix_ typename senf::ConcretePacket<PacketType>::factory_t
180 senf::ConcretePacket<PacketType>::factory()
181 {
182     return interpreter::factory();
183 }
184
185 // Create completely new packet
186
187 template <class PacketType>
188 prefix_ senf::ConcretePacket<PacketType>
189 senf::ConcretePacket<PacketType>::create()
190 {
191     return ConcretePacket(interpreter::create());
192 }
193
194 template <class PacketType>
195 prefix_ senf::ConcretePacket<PacketType>
196 senf::ConcretePacket<PacketType>::create(senf::NoInit_t)
197 {
198     return ConcretePacket(interpreter::create(senf::noinit));
199 }
200
201 template <class PacketType>
202 prefix_ senf::ConcretePacket<PacketType>
203 senf::ConcretePacket<PacketType>::create(size_type size)
204 {
205     return ConcretePacket(interpreter::create(size));
206 }
207
208 template <class PacketType>
209 prefix_ senf::ConcretePacket<PacketType>
210 senf::ConcretePacket<PacketType>::create(size_type size, senf::NoInit_t)
211 {
212     return ConcretePacket(interpreter::create(size,senf::noinit));
213 }
214
215 #ifndef DOXYGEN
216
217 template <class PacketType>
218 template <class ForwardReadableRange>
219 prefix_ senf::ConcretePacket<PacketType> senf::ConcretePacket<PacketType>::
220 create(ForwardReadableRange const & range,
221        typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type *)
222 {
223     return ConcretePacket(interpreter::create(range));
224 }
225
226 #endif
227
228 // Create packet as new packet after a given packet
229
230 template <class PacketType>
231 prefix_ senf::ConcretePacket<PacketType>
232 senf::ConcretePacket<PacketType>::createAfter(Packet const & packet)
233 {
234     return ConcretePacket(interpreter::createAfter(packet.ptr()));
235 }
236
237 template <class PacketType>
238 prefix_ senf::ConcretePacket<PacketType>
239 senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, senf::NoInit_t)
240 {
241     return ConcretePacket(interpreter::createAfter(packet.ptr(),senf::noinit));
242 }
243
244 template <class PacketType>
245 prefix_ senf::ConcretePacket<PacketType>
246 senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, size_type size)
247 {
248     return ConcretePacket(interpreter::createAfter(packet.ptr(), size));
249 }
250
251 template <class PacketType>
252 prefix_ senf::ConcretePacket<PacketType>
253 senf::ConcretePacket<PacketType>::createAfter(Packet const & packet, size_type size,
254                                               senf::NoInit_t)
255 {
256     return ConcretePacket(interpreter::createAfter(packet.ptr(), size, senf::noinit));
257 }
258
259 #ifndef DOXYGEN
260
261 template <class PacketType>
262 template <class ForwardReadableRange>
263 prefix_ senf::ConcretePacket<PacketType> senf::ConcretePacket<PacketType>::
264 createAfter(Packet const & packet, ForwardReadableRange const & range,
265             typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type *)
266 {
267     return ConcretePacket(interpreter::createAfter(packet.ptr(), range));
268 }
269
270 #endif
271
272 // Create packet as new packet (header) before a given packet
273
274 template <class PacketType>
275 prefix_ senf::ConcretePacket<PacketType>
276 senf::ConcretePacket<PacketType>::createBefore(Packet const & packet)
277 {
278     return ConcretePacket(interpreter::createBefore(packet.ptr()));
279 }
280
281 template <class PacketType>
282 prefix_ senf::ConcretePacket<PacketType>
283 senf::ConcretePacket<PacketType>::createBefore(Packet const & packet, senf::NoInit_t)
284 {
285     return ConcretePacket(interpreter::createBefore(packet.ptr(), senf::noinit));
286 }
287
288 template <class PacketType>
289 prefix_ senf::ConcretePacket<PacketType>
290 senf::ConcretePacket<PacketType>::createInsertBefore(Packet const & packet)
291 {
292     return ConcretePacket(interpreter::createInsertBefore(packet.ptr()));
293 }
294
295 template <class PacketType>
296 prefix_ senf::ConcretePacket<PacketType>
297 senf::ConcretePacket<PacketType>::createInsertBefore(Packet const & packet, senf::NoInit_t)
298 {
299     return ConcretePacket(interpreter::createInsertBefore(packet.ptr(), senf::noinit));
300 }
301
302 // Create a clone of the current packet
303
304 template <class PacketType>
305 prefix_ senf::ConcretePacket<PacketType>
306 senf::ConcretePacket<PacketType>::clone()
307     const
308 {
309     return ConcretePacket(ptr()->clone());
310 }
311
312 // Field access
313
314 template <class PacketType>
315 prefix_ typename senf::ConcretePacket<PacketType>::Parser
316 senf::ConcretePacket<PacketType>::parser()
317     const
318 {
319     return ptr()->fields();
320 }
321
322 template <class PacketType>
323 prefix_ typename senf::ConcretePacket<PacketType>::ParserProxy
324 senf::ConcretePacket<PacketType>::operator->()
325     const
326 {
327     return ParserProxy(parser());
328 }
329
330 template <class PacketType>
331 prefix_ senf::Packet senf::ConcretePacket<PacketType>::next(NoThrow_t)
332     const
333 {
334     PacketInterpreterBase::ptr p (Packet::ptr()->next());
335     if (p) return Packet(p);
336     PacketInterpreterBase::optional_range r (type::nextPacketRange(*this));
337     return (r && ! r->empty()) ? getNext(r) : Packet();
338 }
339
340 // private members
341
342 template <class PacketType>
343 prefix_ senf::ConcretePacket<PacketType>::ConcretePacket(typename interpreter::ptr const & packet_)
344     : Packet(packet_)
345 {}
346
347 template <class PacketType>
348 prefix_ typename senf::ConcretePacket<PacketType>::interpreter * senf::ConcretePacket<PacketType>::ptr()
349     const
350 {
351     return static_cast< PacketInterpreter<PacketType> *>( Packet::ptr().get());
352 }
353
354 //-/////////////////////////////////////////////////////////////////////////////////////////////////
355 #undef prefix_
356
357 \f
358 // Local Variables:
359 // mode: c++
360 // fill-column: 100
361 // c-file-style: "senf"
362 // indent-tabs-mode: nil
363 // ispell-local-dictionary: "american"
364 // compile-command: "scons -u test"
365 // comment-column: 40
366 // End: