// $Id$
//
-// Copyright (C) 2006
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
//
// 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
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Definition of inline non-template functions
-
-#include "Packet.ih"
+/** \file
+ \brief Packet inline non-template implementation */
// Custom includes
+#include "../Utils/senfassert.hh"
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
-prefix_ senf::impl::PacketImpl::PacketImpl()
- : data_(), interpreters_(), refcount_(1)
-{
- SATCOM_PKF_REFC_MSG("] PacketImpl::PacketImpl (" << this << "): refcount_ = 1\n");
-}
+///////////////////////////////////////////////////////////////////////////
+// senf::Packet
-prefix_ senf::impl::PacketImpl::PacketImpl(unsigned size, Packet::byte initValue)
- : data_(size,initValue), interpreters_(), refcount_(1)
-{
- SATCOM_PKF_REFC_MSG("] PacketImpl::PacketImpl (" << this << "): refcount_ = 1\n");
-}
+// protected members
-prefix_ senf::impl::PacketImpl::~PacketImpl()
-{
- BOOST_ASSERT( !refcount_ );
- SATCOM_PKF_REFC_MSG("] PacketImpl::~PacketImpl (" << this << ")\n");
-}
+prefix_ senf::Packet::Packet(PacketInterpreterBase::ptr packet)
+ : packet_(packet)
+{}
-// PacketImpl::add_ref and PacketImpl::release are only called from
-// intrusive_ptr_add_ref and intrusive_ptr_release
-prefix_ void senf::impl::PacketImpl::add_ref()
+prefix_ senf::PacketInterpreterBase::ptr senf::Packet::ptr()
+ const
{
- ++refcount_;
- SATCOM_PKF_REFC_MSG("] PacketImpl::add_ref (" << this << "): refcount_ = " << refcount_ << "\n");
+ SENF_ASSERT(packet_);
+ return packet_;
}
-prefix_ bool senf::impl::PacketImpl::release()
+// public structors
+
+prefix_ senf::Packet::Packet()
+{}
+
+// public members
+
+prefix_ senf::Packet senf::Packet::clone()
+ const
{
- BOOST_ASSERT( refcount_ > 0 );
- --refcount_;
- SATCOM_PKF_REFC_MSG("] PacketImpl::release (" << this << "): refcount_ = " << refcount_ << "\n");
- return ! refcount_;
+ return Packet(ptr()->clone());
}
-prefix_ void senf::impl::PacketImpl::truncateInterpreters(Packet const * p)
+// Interpreter chain access
+
+prefix_ senf::Packet senf::Packet::next(NoThrow_t)
+ const
{
- BOOST_ASSERT( p->impl_ == this );
- this->interpreters_.erase(p->self_,this->interpreters_.end());
+ PacketInterpreterBase::ptr p (ptr()->next());
+ return !p && ptr()->nextPacketRange() ? checkNext() : Packet(p);
}
-prefix_ void senf::impl::PacketImpl::truncateInterpretersAfter(Packet const * p)
+prefix_ senf::Packet senf::Packet::next()
+ const
{
- BOOST_ASSERT( p->impl_ == this );
- this->interpreters_.erase(boost::next(p->self_),this->interpreters_.end());
+ Packet p (next(nothrow));
+ if (!p) throw InvalidPacketChainException();
+ return p;
}
-prefix_ senf::impl::PacketImpl* senf::impl::PacketImpl::impl(Packet const * p)
+prefix_ senf::Packet senf::Packet::prev(NoThrow_t)
+ const
{
- return p->impl_;
+ return Packet(ptr()->prev());
}
-/*
-prefix_ std::ostream & senf::operator<<(std::ostream & os, Packet const & packet)
+prefix_ senf::Packet senf::Packet::prev()
+ const
{
- packet.dump(os);
- return os;
+ Packet p (prev(nothrow));
+ if (!p) throw InvalidPacketChainException();
+ return p;
}
-*/
-// These methods are called by the user codes Packet::ptr's. They
-// refcount both the Packet and the owning PacketImpl.
-prefix_ void senf::intrusive_ptr_add_ref(Packet const * p)
+prefix_ senf::Packet senf::Packet::first()
+ const
{
- impl::PacketImpl::packet_add_ref(p);
+ return Packet(ptr()->first());
}
-prefix_ void senf::intrusive_ptr_release(Packet * p)
+prefix_ senf::Packet senf::Packet::last()
+ const
{
- impl::PacketImpl::packet_release(p);
+ Packet p (ptr()->last());
+ return p.next(nothrow) ? checkLast() : p;
}
-prefix_ void senf::impl::intrusive_ptr_add_ref(PacketImpl * p)
+prefix_ senf::Packet senf::Packet::parseNextAs(factory_t factory)
+ const
{
- p->add_ref();
+ return Packet(ptr()->parseNextAs(factory));
}
-prefix_ void senf::impl::intrusive_ptr_release(PacketImpl * p)
+prefix_ senf::Packet senf::Packet::append(Packet const & packet)
+ const
{
- if (p->release())
- delete p;
+ return Packet(ptr()->append(packet.ptr()));
}
-///////////////////////////////////////////////////////////////////////////
-// class Packet
+// Data access
-prefix_ senf::Packet::iterator senf::Packet::begin()
+prefix_ senf::PacketData & senf::Packet::data()
const
{
- return impl_->data_.begin()+begin_;
+ return ptr()->data();
}
-prefix_ senf::Packet::iterator senf::Packet::end()
+prefix_ senf::Packet::size_type senf::Packet::size()
const
{
- return impl_->data_.begin()+end_;
+ return data().size();
}
-prefix_ size_t senf::Packet::size()
+
+// Other methods
+
+prefix_ bool senf::Packet::operator==(Packet const & other)
const
{
- return end_-begin_;
+ return ptr() == other.ptr();
}
-prefix_ senf::Packet::ptr senf::Packet::prev()
- const
+prefix_ void senf::Packet::finalizeThis()
{
- if (this->self_ == this->impl_->interpreters_.begin())
- return ptr(0);
- // 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(boost::prior(this->self_)->get(),true);
+ ptr()->finalizeThis();
}
-prefix_ senf::Packet::ptr senf::Packet::head()
- const
+prefix_ void senf::Packet::finalizeTo(Packet const & other)
+{
+ ptr()->finalizeTo(other.ptr());
+}
+
+prefix_ void senf::Packet::finalizeAll()
{
- // 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(this->impl_->interpreters_.front().get(),true);
+ ptr()->finalizeTo(last().ptr());
}
-prefix_ senf::Packet::~Packet()
+prefix_ void senf::Packet::dump(std::ostream & os)
+ const
{
- /** \fixme This is bad ... we cannot check this since this
- assertion fails at the moment if the Packet constructor throws
- ... hrmpf ... we really need to initialize refcount_ to 0 and
- remove the 'false' argument to the ptr constructor in create */
- // BOOST_ASSERT( !this->refcount_ && !this->impl_ );
- SATCOM_PKF_REFC_MSG("] Packet::~Packet (" << this << ")\n");
+ last(); // Make sure the packet is complete
+ ptr()->dump(os);
}
-prefix_ void senf::Packet::add_ref()
+prefix_ senf::TypeIdValue senf::Packet::typeId()
const
{
- ++this->refcount_;
- SATCOM_PKF_REFC_MSG("] Packet::add_ref (" << this << "): refcount_ = " << this->refcount_ << "\n");
+ return ptr()->typeId();
}
-prefix_ bool senf::Packet::release()
+prefix_ senf::Packet::factory_t senf::Packet::factory()
+ const
{
- BOOST_ASSERT( this->refcount_ > 0 );
- --this->refcount_;
- SATCOM_PKF_REFC_MSG("] Packet::release (" << this << "): refcount_ = " << this->refcount_ << "\n");
- return !this->refcount_ && !this->impl_;
+ return ptr()->factory();
}
-prefix_ bool senf::Packet::unlink()
+prefix_ bool senf::Packet::boolean_test()
+ const
{
- SATCOM_PKF_REFC_MSG("] Packet::unlink (" << this << "): refcount_ = " << this->refcount_ << "\n");
- this->impl_ = 0;
- this->begin_ = this->end_;
- return !this->refcount_;
+ return packet_ && packet_->valid();
}
///////////////////////////////cci.e///////////////////////////////////////
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
// End: