4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief PacketImpl non-inline non-template implementation */
26 #include "PacketImpl.ih"
30 #include <boost/format.hpp>
31 #include <senf/Utils/String.hh>
34 //#include "PacketImpl.mpp"
36 ///////////////////////////////cc.p////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////////////
39 // senf::detail::PacketImpl
41 prefix_ senf::detail::PacketImpl::~PacketImpl()
43 // We increment refcount_ to ensure, release() won't call delete again
45 eraseInterpreters(interpreters_.begin(), interpreters_.end());
50 prefix_ void senf::detail::PacketImpl::appendInterpreter(PacketInterpreterBase * p)
52 interpreters_.push_back(*p);
56 prefix_ void senf::detail::PacketImpl::prependInterpreter(PacketInterpreterBase * p)
58 interpreters_.push_front(*p);
62 prefix_ void senf::detail::PacketImpl::prependInterpreter(PacketInterpreterBase * p,
63 PacketInterpreterBase * before)
65 interpreter_list::iterator i (interpreter_list::current(*before));
66 interpreters_.insert(i, *p);
72 prefix_ void senf::detail::PacketImpl::clear(PacketData * self)
74 PacketInterpreterBase * n (next(static_cast<PacketInterpreterBase*>(self)));
76 truncateInterpreters(n);
77 iterator first (boost::next(begin(),self->begin_));
78 data_.erase(first, boost::next(begin(),self->end_));
79 updateIterators(self,self->begin_,-self->size());
84 prefix_ void senf::detail::PacketImpl::eraseInterpreters(interpreter_list::iterator b,
85 interpreter_list::iterator e)
88 interpreter_list::iterator i (b++);
89 PacketInterpreterBase * p (&(*i));
90 interpreters_.erase(i);
91 p->releaseImpl(); // might call PacketImpl::release and might delete p
95 prefix_ void senf::detail::PacketImpl::updateIterators(PacketData * self, difference_type pos,
98 // I hate to change the PacketData representation from here, I would have preferred to let
99 // PacketData have authority over this but trying that just get's to convoluted so I choose the
100 // simple solution and made PacketImpl a friend of PacketData.
102 interpreter_list::iterator i (interpreters_.begin());
104 // There are three types of packets
105 // a) Those which come before 'self' in the interpreter chain
107 // c) Those that come afterwards
108 // For a), the change must be inside the packet since 'self' must be within those packets
109 // For b), the change must also be within since that's the packet we are changeing
110 // For c), the change must be outside the packet (we don't allow an upper packet to mess with
111 // the the data owned by a packet further down the chain). It can be before or after the
115 for (; &(*i) != static_cast<PacketInterpreterBase*>(self); ++i) i->end_ += n;
121 interpreter_list::iterator const i_end (interpreters_.end());
123 if (pos <= difference_type(i->begin_))
124 // pos is before the packet, it must then be before all futher packets ...
125 for (; i != i_end; ++i) {
129 // else pos is after the packet and we don't need to change anything ...
134 prefix_ void senf::detail::PacketImpl::dumpAnnotations(std::ostream & os)
136 for (AnnotationRegistry::key_t key (AnnotationRegistry::instance().keyBegin());
137 key != AnnotationRegistry::instance().keyEnd(); ++key) {
138 void * antn (annotation(key));
140 AnnotationRegistry::instance().dump(key, os, antn);
144 prefix_ void * senf::detail::PacketImpl::complexAnnotation(AnnotationRegistry::key_t key)
146 SENF_ASSERT( key<0, "complexAnnotation called with invalid key");
147 #ifdef SENF_PACKET_NO_COMPLEX_ANNOTATIONS
150 while (complexAnnotations_.size() < ComplexAnnotations::size_type(-key))
151 complexAnnotations_.push_back(0);
152 if (complexAnnotations_.is_null(-key-1))
154 return complexAnnotations_[-key-1].get();
158 ///////////////////////////////////////////////////////////////////////////
159 // senf::detail::AnnotationRegistry
161 prefix_ void senf::detail::AnnotationRegistry::dumpRegistrations(std::ostream & os)
164 boost::format fmt ("%4.4s %-56.56s %-7.7s %5d\n");
165 os << "SENF_PACKET_ANNOTATION_SLOTS = " << SENF_PACKET_ANNOTATION_SLOTS << "\n"
166 << "SENF_PACKET_ANNOTATION_SLOTSIZE = " << SENF_PACKET_ANNOTATION_SLOTSIZE << "\n";
167 os << fmt % "SLOT" % "TYPE" % "COMPLEX" % "SIZE";
168 for (key_t key (keyBegin()); key != keyEnd(); ++key) {
169 std::string nm (name(key));
170 if (nm.size() > 56) nm.erase(nm.begin(), nm.begin()+nm.size()-32);
172 % (key >= 0 ? senf::str(key) : "")
174 % (isComplex(key) ? "yes" : "no")
180 prefix_ void senf::dumpPacketAnnotationRegistry(std::ostream & os)
182 senf::detail::AnnotationRegistry::instance().dumpRegistrations(os);
185 /////////////////////////////cc.e////////////////////////////////////////
187 //#include "PacketImpl.mpp"
193 // c-file-style: "senf"
194 // indent-tabs-mode: nil
195 // ispell-local-dictionary: "american"
196 // compile-command: "scons -u test"
197 // comment-column: 40