948698da80bd345919bb2547c2a79991b7ec10a0
[senf.git] / Packets / Packet.ct
1 // $Id$
2 //
3 // Copyright (C) 2006 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@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 // Definition of non-inline template functions
24
25 #include "Packet.ih"
26
27 // Custom includes
28 #include <algorithm>
29 #include "ParserBase.hh"
30
31 #define prefix_
32 ///////////////////////////////ct.p////////////////////////////////////////
33
34 template <class OtherPacket, class InputIterator>
35 prefix_ typename senf::Packet::ptr_t<OtherPacket>::ptr
36 senf::Packet::create(InputIterator b, InputIterator e)
37 {
38     boost::intrusive_ptr<impl::PacketImpl> impl (new impl::PacketImpl(b,e),false);
39     if (!check<OtherPacket>(impl->data_.begin(),impl->data_.end()))
40         throw TruncatedPacketException();
41     typename ptr_t<OtherPacket>::ptr p (new OtherPacket(PacketOp_set(impl.get())), false);
42     return p;
43 }
44
45 template <class OtherPacket>
46 prefix_ typename senf::Packet::ptr_t<OtherPacket>::ptr senf::Packet::create()
47 {
48     boost::intrusive_ptr<impl::PacketImpl> impl (
49         new impl::PacketImpl(min_bytes<OtherPacket>(),0));
50     typename ptr_t<OtherPacket>::ptr p (new OtherPacket(PacketOp_set(impl.get())), false);
51     p->init();
52     return p;
53 }
54
55 template <class OuterPacket>
56 prefix_ typename senf::Packet::ptr_t<OuterPacket>::ptr
57 senf::Packet::create(Packet::ptr payload)
58 {
59     /** \todo should I instead of using head() throw away all
60         interpreters before payload? ... probably yes ... */
61     payload->insert(payload->head()->begin(),min_bytes<OuterPacket>(),0);
62     typename ptr_t<OuterPacket>::ptr p (new OuterPacket(PacketOp_set(payload->impl_)));
63     p->init();
64     return p;
65 }
66
67 template <class OtherPacket>
68 prefix_ typename senf::Packet::ptr_t<OtherPacket>::ptr senf::Packet::reinterpret()
69 {
70     // THIS INVALIDATES this !!!!!!!
71     if (!check<OtherPacket>(begin(),end()))
72         throw TruncatedPacketException();
73     typename ptr_t<OtherPacket>::ptr p (new OtherPacket(PacketOp_replace(this)),false);
74     return p;
75 }
76
77 template <class OtherPacket>
78 prefix_ typename senf::Packet::ptr_t<OtherPacket>::ptr
79 senf::Packet::registerInterpreter(raw_container::iterator begin,
80                                          raw_container::iterator end)
81     const
82 {
83     if (!check<OtherPacket>(begin,end))
84         throw TruncatedPacketException();
85     typename ptr_t<OtherPacket>::ptr p (
86         new OtherPacket(PacketOp_register(begin-impl_->data_.begin(),
87                                           end-impl_->data_.begin(),
88                                           this)),
89         false);
90     return p;
91 }
92
93 #define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Packets/Packet.mpp", 4))
94 #include BOOST_PP_ITERATE()
95
96 template <class OtherPacket>
97 prefix_ typename senf::Packet::ptr_t<OtherPacket>::ptr senf::Packet::find_next()
98     const
99 {
100     ptr p (next());
101     while (p && !p->is<OtherPacket>())
102         p = p->next();
103     return p->as<OtherPacket>();
104 }
105
106 template <class OtherPacket>
107 prefix_ typename senf::Packet::ptr_t<OtherPacket>::ptr senf::Packet::find_prev()
108     const
109 {
110     ptr p (prev());
111     while (p && !p->is<OtherPacket>())
112         p = p->prev();
113     return p->as<OtherPacket>();
114 }
115
116 template <class OtherPacket>
117 prefix_ typename senf::Packet::ptr_t<OtherPacket>::ptr senf::Packet::get_next()
118     const
119 {
120     typename ptr_t<OtherPacket>::ptr p (find_next<OtherPacket>());
121     BOOST_ASSERT(p);
122     return p;
123 }
124
125 template <class OtherPacket>
126 prefix_ typename senf::Packet::ptr_t<OtherPacket>::ptr senf::Packet::get_prev()
127     const
128 {
129     typename ptr_t<OtherPacket>::ptr p (find_prev<OtherPacket>());
130     BOOST_ASSERT(p);
131     return p;
132 }
133
134 template <class InputIterator>
135 prefix_ void senf::Packet::insert(iterator pos, InputIterator f, InputIterator l,
136                                          Whence whence)
137 {
138     size_type index(pos-impl_->data_.begin());
139     BOOST_ASSERT( index >= begin_ && index <= end_ );
140     size_type sz (impl_->data_.size());
141     impl_->data_.insert(pos,f,l);
142     impl_->updateIterators(index,impl_->data_.size()-sz,self_,whence);
143 }
144
145 ///////////////////////////////ct.e////////////////////////////////////////
146 #undef prefix_
147
148 \f
149 // Local Variables:
150 // mode: c++
151 // c-file-style: "senf"
152 // End: