4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
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
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.
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.
19 // The Original Code is Fraunhofer FOKUS code.
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.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief PacketImpl non-inline non-template implementation */
31 #include "PacketImpl.ih"
37 #include <boost/format.hpp>
38 #include <senf/Utils/String.hh>
41 //#include "PacketImpl.mpp"
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
46 // senf::detail::PacketImpl
48 prefix_ senf::detail::PacketImpl::~PacketImpl()
50 // We increment refcount_ to ensure, release() won't call delete again
52 eraseInterpreters(interpreters_.begin(), interpreters_.end());
55 prefix_ void senf::detail::PacketImpl::release()
57 SENF_ASSERT(refcount_ >= 1, "Internal failure: Releasing dead PacketImpl ??");
58 // uah ... we need to be extremely careful here. If refcount_ is 1, we want to commit suicide,
59 // however the destructor will remove all PacketInterpreters from the list and will thereby
60 // decrement refcount -> only decrement refcount_ when *not* calling delete (otherwise
61 // the assert above will fail)
70 prefix_ void senf::detail::PacketImpl::appendInterpreter(PacketInterpreterBase * p)
72 interpreters_.push_back(*p);
76 prefix_ void senf::detail::PacketImpl::prependInterpreter(PacketInterpreterBase * p)
78 interpreters_.push_front(*p);
82 prefix_ void senf::detail::PacketImpl::prependInterpreter(PacketInterpreterBase * p,
83 PacketInterpreterBase * before)
85 interpreter_list::iterator i (interpreter_list::current(*before));
86 interpreters_.insert(i, *p);
92 prefix_ void senf::detail::PacketImpl::clear(PacketData * self)
94 PacketInterpreterBase * n (next(static_cast<PacketInterpreterBase*>(self)));
96 truncateInterpreters(n);
97 iterator first (boost::next(begin(),self->begin_));
98 data_.erase(first, boost::next(begin(),self->end_));
99 updateIterators(self,self->begin_,-self->size());
104 prefix_ void senf::detail::PacketImpl::eraseInterpreters(interpreter_list::iterator b,
105 interpreter_list::iterator e)
108 interpreter_list::iterator i (b++);
109 PacketInterpreterBase * p (&(*i));
110 interpreters_.erase(i);
111 p->releaseImpl(); // might call PacketImpl::release and might delete p
115 prefix_ void senf::detail::PacketImpl::updateIterators(PacketData * self, difference_type pos,
118 // I hate to change the PacketData representation from here, I would have preferred to let
119 // PacketData have authority over this but trying that just get's to convoluted so I choose the
120 // simple solution and made PacketImpl a friend of PacketData.
122 interpreter_list::iterator i (interpreters_.begin());
124 // There are three types of packets
125 // a) Those which come before 'self' in the interpreter chain
127 // c) Those that come afterwards
128 // For a), the change must be inside the packet since 'self' must be within those packets
129 // For b), the change must also be within since that's the packet we are changing
130 // For c), the change must be outside the packet (we don't allow an upper packet to mess with
131 // the the data owned by a packet further down the chain). It can be before or after the
135 for (; &(*i) != static_cast<PacketInterpreterBase*>(self); ++i) i->end_ += n;
141 interpreter_list::iterator const i_end (interpreters_.end());
143 if (pos <= difference_type(i->begin_))
144 // pos is before the packet, it must then be before all further packets ...
145 for (; i != i_end; ++i) {
149 // else pos is after the packet and we don't need to change anything ...
154 prefix_ void senf::detail::PacketImpl::dumpAnnotations(std::ostream & os)
156 for (AnnotationRegistry::iterator i (AnnotationRegistry::instance().begin());
157 i != AnnotationRegistry::instance().end(); ++i) {
158 void * antn (annotation(*i));
160 AnnotationRegistry::instance().dump(*i, os, antn);
164 prefix_ void senf::detail::PacketImpl::clearAnnotations()
166 ::memset(simpleAnnotations_, 0, sizeof(simpleAnnotations_));
167 complexAnnotations_.clear();
170 prefix_ void senf::detail::PacketImpl::assignAnnotations(PacketImpl const & other)
172 std::copy(&other.simpleAnnotations_[0], &other.simpleAnnotations_[0] +
173 sizeof(simpleAnnotations_)/sizeof(simpleAnnotations_[0]), simpleAnnotations_);
174 complexAnnotations_.assign(
175 other.complexAnnotations_.begin(), other.complexAnnotations_.end());
178 prefix_ void * senf::detail::PacketImpl::complexAnnotation(AnnotationRegistry::key_type key)
180 SENF_ASSERT( key < 0, "complexAnnotation called with invalid key");
181 return (ComplexAnnotations::size_type(-key-1) >= complexAnnotations_.size()
182 || complexAnnotations_.is_null(-key-1))
183 ? 0 : complexAnnotations_[-key-1].get();
186 //-/////////////////////////////////////////////////////////////////////////////////////////////////
187 // senf::detail::AnnotationRegistry
189 prefix_ void senf::detail::AnnotationRegistry::dump(key_type key, std::ostream & os,
193 Registry::const_iterator i (registry_.find(key));
194 if (i != registry_.end()) {
195 os << fieldName(i->second->v_name());
196 i->second->v_dump(os, annotation);
201 prefix_ void senf::detail::AnnotationRegistry::dumpRegistrations(std::ostream & os)
203 boost::format fmt ("%-56.56s %-4.4s %-7.7s %5d\n");
204 os << "SENF_PACKET_ANNOTATION_SLOTS = " << SENF_PACKET_ANNOTATION_SLOTS << "\n"
205 << "SENF_PACKET_ANNOTATION_SLOTSIZE = " << SENF_PACKET_ANNOTATION_SLOTSIZE << "\n";
206 os << fmt % "TYPE" % "FAST" % "COMPLEX" % "SIZE";
208 for (Index::const_iterator i (index_.begin()), i_end (index_.end()); i != i_end; ++i) {
209 key_type key (i->second);
210 std::string nm (i->first);
211 if (nm.size() > 56) nm.erase(nm.begin(), nm.begin()+nm.size()-32);
214 % (key >= 0 ? "yes" : "no")
215 % (isComplex(key) ? "yes" : "no")
220 prefix_ void senf::dumpPacketAnnotationRegistry(std::ostream & os)
222 senf::detail::AnnotationRegistry::instance().dumpRegistrations(os);
225 //-/////////////////////////////////////////////////////////////////////////////////////////////////
227 //#include "PacketImpl.mpp"
233 // c-file-style: "senf"
234 // indent-tabs-mode: nil
235 // ispell-local-dictionary: "american"
236 // compile-command: "scons -u test"
237 // comment-column: 40