X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FPacket.cc;h=06d646353ffc3aae49879190dff58a7855482718;hb=5443435c4c2b6e4386c5334b5b8358273f2bae93;hp=0ca332195ca02536d1832d58a614cb175c0c5497;hpb=145f6a7d0f3a6aaa77b3625351c952d24cb0b8a1;p=senf.git diff --git a/Packets/Packet.cc b/Packets/Packet.cc index 0ca3321..06d6463 100644 --- a/Packets/Packet.cc +++ b/Packets/Packet.cc @@ -1,9 +1,9 @@ // $Id$ // -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,273 +20,47 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// Definition of non-inline non-template functions +/** \file + \brief Packet non-inline non-template implementation */ -#include "Packet.hh" -#include "Packet.ih" +//#include "Packet.ih" // Custom includes -#include // for next/prior +#include "Packets.hh" +//#include "Packet.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -// REFERENCE COUNTING -/////////////////////////////////////////////////////////////////////////// - -// We manage TWO reference counts: -// -// - The first reference counts lives wihin PacketImpl. It counts the -// number of references to the PacketImpl instance -// -// - The second reference count lives with the Packet interpreters. It -// counts the number of external references to the Packet facades. -// -// The PacketImpl refcount is always the sum of all it's Packet -// interpreter member refcounts. -// -// The Packet facades are referenced from two sides: -// -// - From the user. These references are counted in the Packet -// refcount. -// -// - From the list of interpreters. These references are *not* -// counted. -// -// The Packet facades have an impl_ member. This is set to non-0 only, -// as long as the Packet is a list member. The Packet may be deleted, -// when impl_ == 0 and refcount_ == 0. - -// class ListPacketDeleter - -// This is the custom deleter used for the pointers in the -// interpreters list. This deleter is only called, when the Packet is -// removed from the interpreters list. -prefix_ void senf::impl::ListPacketDeleter::operator()(Packet * p) -{ - PacketImpl * impl = PacketImpl::impl(p); - if (impl->releaseInterpreter(p)) - delete impl; -} - -// struct PacketImpl - -prefix_ senf::Packet::interpreter_list::iterator -senf::impl::PacketImpl::appendInterpreter(Packet * p) -{ - BOOST_ASSERT( p->impl_ == 0 ); - - this->refcount_ += p->refcount_; - SATCOM_PKF_REFC_MSG("] PacketImpl::appendInterpreter (" << this << "): refcount_ = " << refcount_ << "\n"); - p->impl_ = this; - this->interpreters_.push_back( - boost::shared_ptr(p, impl::ListPacketDeleter())); - - p->self_ = boost::prior(this->interpreters_.end()); - return p->self_; -} - -prefix_ senf::Packet::interpreter_list::iterator -senf::impl::PacketImpl::prependInterpreter(Packet * p) -{ - BOOST_ASSERT( p->impl_ == 0 ); - - this->refcount_ += p->refcount_; - SATCOM_PKF_REFC_MSG("] PacketImpl::prependInterpreter (" << this << "): refcount_ = " << refcount_ << "\n"); - p->impl_ = this; - this->interpreters_.push_front( - boost::shared_ptr(p, impl::ListPacketDeleter())); - - p->self_ = this->interpreters_.begin(); - return p->self_; -} - -// Called, whenever a Packet is removed from the list by the -// ListPacketDeleter; -prefix_ bool senf::impl::PacketImpl::releaseInterpreter(Packet * p) -{ - // We have to be extra careful here: This method might be called - // AFTER the PacketImpl instance has already been destructed while - // destructing the interpreters list !! - // If p->refcount_ is > 0 however we know, that this->refcount_ - // must also be > 0 ... - // So we have to make sure never to access this if p->refcount_==0 - BOOST_ASSERT( p->impl_ == this ); - bool rv (false); - if (p->refcount_ > 0) { - this->refcount_ -= p->refcount_; - rv = !this->refcount_; - SATCOM_PKF_REFC_MSG("] PacketImpl::releaseInterpreter (" << this << "): refcount_ = " << refcount_ << "\n"); - } - if (p->unlink()) - delete p; - return rv; -} - -namespace { - bool whenceCmp(unsigned a, unsigned b, bool end, senf::Packet::Whence whence) - { - using senf::Packet; - return ((whence == Packet::OUTSIDE && ! end) - || whence == Packet::BEFORE - || (whence == Packet::INSIDE && end)) ? a>=b : a>b; - } -} - -prefix_ void -senf::impl::PacketImpl::updateIterators(Packet::size_type index, - Packet::difference_type n, - Packet::interpreter_list::iterator self, - Packet::Whence whence) -{ - Packet::interpreter_list::iterator i (interpreters_.begin()); - Packet::interpreter_list::iterator const e (interpreters_.end()); - Packet::Whence w (whence == Packet::AUTO ? Packet::INSIDE : whence); - for (;i!=e;++i) { - if (whenceCmp((*i)->end_,index,true,w)) - if (n<0 && (*i)->end_ < index-n) - (*i)->end_ = index; - else - (*i)->end_ += n; - if (whenceCmp((*i)->begin_,index,false,w)) - if (n<0 && (*i)->begin_ < index-n) - (*i)->begin_ = index; - else - (*i)->begin_ += n; - if (i == self && whence == Packet::AUTO) w = Packet::OUTSIDE; - BOOST_ASSERT( (*i)->end_ >= (*i)->begin_ ); - } -} - -prefix_ void senf::impl::PacketImpl::packet_add_ref(Packet const * p) -{ - p->add_ref(); - if (p->impl_) - p->impl_->add_ref(); -} - -prefix_ void senf::impl::PacketImpl::packet_release(Packet * p) -{ - bool del (p->release()); - if (p->impl_ && p->impl_->release()) - // In this case, del is certainly false here. p might - // however get deleted now. - delete p->impl_; - if (del) - delete p; -} - -/////////////////////////////////////////////////////////////////////////// -// class Packet - -prefix_ senf::Packet::ptr senf::Packet::next() +prefix_ senf::Packet senf::Packet::checkNext() const { - interpreter_list::iterator n = boost::next(this->self_); - if (n == this->impl_->interpreters_.end()) { - if (this->parsed_) - return ptr(0); - /* \fixme v_nextInterpreter return bool? new Interpreter to be - added ? hmm ... this however is quite suboptimal ... */ - this->v_nextInterpreter(); - this->parsed_ = true; - n = boost::next(this->self_); - if (n == this->impl_->interpreters_.end()) - return ptr(0); + PacketInterpreterBase::optional_range r (ptr()->nextPacketRange()); + if (r && ! r->empty()) { + factory_t factory (ptr()->nextPacketType()); + if (factory) + return parseNextAs(factory); + else + return parseNextAs(); } - // Re-converting the Packet to a smart pointer is correct here, - // since the shared_ptr really uses the intrusive refcount which - // makes this operation safe ... - return ptr(n->get(),true); + return Packet(); } -prefix_ senf::Packet::ptr senf::Packet::last() +prefix_ senf::Packet senf::Packet::checkLast() const { - Packet * p = this->impl_->interpreters_.back().get(); - while (! p->parsed_) { - Packet * pp = p->next().get(); - if (pp) p = pp; + Packet p (*this); + Packet n (p.next(nothrow)); + while (n) { + p = n; + n = p.next(nothrow); } - // Re-converting the to a smart pointer is correct here, since the - // shared_ptr really uses the intrusive refcount which makes this - // operation safe ... - return ptr(p,true); -} - -prefix_ void senf::Packet::i_registerInterpreter(Packet * p) - const -{ - BOOST_ASSERT( !p->impl_ ); - this->impl_->truncateInterpretersAfter(this); - this->impl_->appendInterpreter(p); - this->parsed_ = true; -} - -prefix_ void senf::Packet::i_replaceInterpreter(Packet * p) -{ - BOOST_ASSERT( !p->impl_ ); - // We need to increment the refcount of impl_ beforehand, - // otherwise it might get deleted by the truncateInterpreters call - boost::intrusive_ptr impl (this->impl_,true); - impl->truncateInterpreters(this); - impl->appendInterpreter(p); -} - -prefix_ void senf::Packet::i_setInterpreter(impl::PacketImpl * i) -{ - // Using prependInterpreter makes this usable for both, the - // create-from-data and wrap-packet constructors - i->prependInterpreter(this); -} - -prefix_ void senf::Packet::insert(iterator pos, byte v, Whence whence) -{ - size_type index(pos-impl_->data_.begin()); - BOOST_ASSERT( index >= begin_ && index <= end_); - impl_->data_.insert(pos,v); - impl_->updateIterators(index,1,self_,whence); -} - -prefix_ void senf::Packet::insert(iterator pos, size_type n, byte v, Whence whence) -{ - size_type index(pos-impl_->data_.begin()); - BOOST_ASSERT( index >= begin_ && index <= end_ ); - impl_->data_.insert(pos,n,v); - impl_->updateIterators(index,n,self_,whence); -} - -prefix_ void senf::Packet::erase(iterator pos) -{ - size_type index(pos-impl_->data_.begin()); - BOOST_ASSERT( index >= begin_ && index < end_ ); - impl_->data_.erase(pos); - impl_->updateIterators(index,-1,self_,INSIDE); -} - -prefix_ void senf::Packet::erase(iterator first, iterator last) -{ - size_type index(first-impl_->data_.begin()); - size_type sz(last-first); - BOOST_ASSERT( index >= begin_ && index < end_ && sz <= end_-index ); - /** \todo Here we should assert, that no bytes belonging to the - next iterator are deleted ... */ - impl_->data_.erase(first,last); - impl_->updateIterators(index,-sz,self_,INSIDE); -} - -prefix_ void senf::Packet::dump(std::ostream & os) - const -{ - v_dump(os); - ptr p (next()); - if (p) - p->dump(os); + return p; } -//////////////////////////////cc.e//////////////////////////////////////// +///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ +//#include "Packet.mpp" // Local Variables: