ea63a0704b692ae0218ee8a9e7603a9028905baa
[senf.git] / Packets / Packet.cci
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 inline non-template functions
24
25 #include "Packet.ih"
26
27 // Custom includes
28
29 #define prefix_ inline
30 ///////////////////////////////cci.p///////////////////////////////////////
31
32 prefix_ senf::impl::PacketImpl::PacketImpl()
33     : data_(), interpreters_(), refcount_(1)
34 {
35     SATCOM_PKF_REFC_MSG("] PacketImpl::PacketImpl (" << this << "): refcount_ = 1\n");
36 }
37
38 prefix_ senf::impl::PacketImpl::PacketImpl(unsigned size, Packet::byte initValue)
39     : data_(size,initValue), interpreters_(), refcount_(1)
40 {
41     SATCOM_PKF_REFC_MSG("] PacketImpl::PacketImpl (" << this << "): refcount_ = 1\n");
42 }
43
44 prefix_ senf::impl::PacketImpl::~PacketImpl()
45 {
46     BOOST_ASSERT( !refcount_ );
47     SATCOM_PKF_REFC_MSG("] PacketImpl::~PacketImpl (" << this << ")\n");
48 }
49
50 // PacketImpl::add_ref and PacketImpl::release are only called from
51 // intrusive_ptr_add_ref and intrusive_ptr_release
52 prefix_ void senf::impl::PacketImpl::add_ref()
53
54     ++refcount_;
55     SATCOM_PKF_REFC_MSG("] PacketImpl::add_ref (" << this << "): refcount_ = " << refcount_ << "\n");
56 }
57
58 prefix_ bool senf::impl::PacketImpl::release()
59
60     BOOST_ASSERT( refcount_ > 0 );
61     --refcount_;
62     SATCOM_PKF_REFC_MSG("] PacketImpl::release (" << this << "): refcount_ = " << refcount_ << "\n");
63     return ! refcount_;
64 }
65
66 prefix_ void senf::impl::PacketImpl::truncateInterpreters(Packet const * p)
67 {
68     BOOST_ASSERT( p->impl_ == this );
69     this->interpreters_.erase(p->self_,this->interpreters_.end());
70 }
71
72 prefix_ void senf::impl::PacketImpl::truncateInterpretersAfter(Packet const * p)
73 {
74     BOOST_ASSERT( p->impl_ == this );
75     this->interpreters_.erase(boost::next(p->self_),this->interpreters_.end());
76 }
77
78 prefix_ senf::impl::PacketImpl* senf::impl::PacketImpl::impl(Packet const * p)
79 {
80     return p->impl_;
81 }
82
83 /*
84 prefix_ std::ostream & senf::operator<<(std::ostream & os, Packet const & packet)
85 {
86     packet.dump(os);
87     return os;
88 }
89 */
90
91 // These methods are called by the user codes Packet::ptr's. They
92 // refcount both the Packet and the owning PacketImpl. 
93 prefix_ void senf::intrusive_ptr_add_ref(Packet const * p)
94 {
95     impl::PacketImpl::packet_add_ref(p);
96 }
97
98 prefix_ void senf::intrusive_ptr_release(Packet * p)
99 {
100     impl::PacketImpl::packet_release(p);
101 }
102
103 prefix_ void senf::impl::intrusive_ptr_add_ref(PacketImpl * p)
104 {
105     p->add_ref();
106 }
107
108 prefix_ void senf::impl::intrusive_ptr_release(PacketImpl * p)
109 {
110     if (p->release())
111         delete p;
112 }
113
114 ///////////////////////////////////////////////////////////////////////////
115 // class Packet
116
117 prefix_ senf::Packet::iterator senf::Packet::begin()
118     const
119 {
120     return impl_->data_.begin()+begin_;
121 }
122
123 prefix_ senf::Packet::iterator senf::Packet::end()
124     const
125 {
126     return impl_->data_.begin()+end_;
127 }
128
129 prefix_ size_t senf::Packet::size()
130     const
131 {
132     return end_-begin_;
133 }
134
135 prefix_ senf::Packet::ptr senf::Packet::prev()
136     const
137 {
138     if (this->self_ == this->impl_->interpreters_.begin())
139         return ptr(0);
140     // Re-converting the to a smart pointer is correct here, since the
141     // shared_ptr really uses the intrusive refcount which makes this
142     // operation safe ...
143     return ptr(boost::prior(this->self_)->get(),true);
144 }
145
146 prefix_ senf::Packet::ptr senf::Packet::head()
147     const
148 {
149     // Re-converting the to a smart pointer is correct here, since the
150     // shared_ptr really uses the intrusive refcount which makes this
151     // operation safe ...
152     return ptr(this->impl_->interpreters_.front().get(),true);
153 }
154
155 prefix_  senf::Packet::~Packet()
156 {
157     /** \fixme This is bad ... we cannot check this since this
158         assertion fails at the moment if the Packet constructor throws
159         ... hrmpf ... we really need to initialize refcount_ to 0 and
160         remove the 'false' argument to the ptr constructor in create */
161     // BOOST_ASSERT( !this->refcount_  && !this->impl_ );
162     SATCOM_PKF_REFC_MSG("] Packet::~Packet (" << this << ")\n");
163 }
164
165 prefix_ void senf::Packet::add_ref()
166     const
167 {
168     ++this->refcount_;
169     SATCOM_PKF_REFC_MSG("] Packet::add_ref (" << this << "): refcount_ = " << this->refcount_ << "\n");
170 }
171
172 prefix_ bool senf::Packet::release()
173 {
174     BOOST_ASSERT( this->refcount_ > 0 );
175     --this->refcount_;
176     SATCOM_PKF_REFC_MSG("] Packet::release (" << this << "): refcount_ = " << this->refcount_ << "\n");
177     return !this->refcount_ && !this->impl_;
178 }
179
180 prefix_ bool senf::Packet::unlink()
181 {
182     SATCOM_PKF_REFC_MSG("] Packet::unlink (" << this << "): refcount_ = " << this->refcount_ << "\n");
183     this->impl_ = 0;
184     this->begin_ = this->end_;
185     return !this->refcount_;
186 }
187
188 ///////////////////////////////cci.e///////////////////////////////////////
189 #undef prefix_
190
191 \f
192 // Local Variables:
193 // mode: c++
194 // c-file-style: "senf"
195 // End: