Skip to content
Snippets Groups Projects
Packet.ih 4.55 KiB
Newer Older
sbund's avatar
sbund committed
// $Id$
//
// Copyright (C) 2006
sbund's avatar
sbund committed
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
//     Stefan Bund <stefan.bund@fokus.fraunhofer.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
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#ifndef IH_Packet_
#define IH_Packet_ 1

// Custom includes

///////////////////////////////ih.p////////////////////////////////////////

#ifdef SATCOM_PKF_REFC_DEBUG
#include <iostream>
#define SATCOM_PKF_REFC_MSG(x) std::cerr << x
#else
#define SATCOM_PKF_REFC_MSG(x)
#endif

sbund's avatar
sbund committed
namespace impl {

    // This deleter is used in the PacketImpl list holding the
    // Packet's. It only decrements the Packet refcount. If this
    // drops to 0 (i.e. the packet is removed from the list and no
    // external reference exists) the packet ist deleted.
    //
    // Since this is called, when the packet is removed from the
    // list, we set the impl_ member to 0 to mark, that the packet
    // is now orphaned and every use should throw an exception ...
    //
    // To make this work we must make sure, that the packet
    // refcount is incremented when we add the packet to the list.
    struct ListPacketDeleter {
        void operator()(Packet * p);
    };

    struct PacketImpl
    {
        Packet::raw_container data_;
        Packet::interpreter_list interpreters_;
        Packet::refcount_t refcount_;

        PacketImpl();
        PacketImpl(unsigned size, Packet::byte initValue);
        ~PacketImpl();
        template <class InputIterator>
        PacketImpl(InputIterator begin, InputIterator end);

        void add_ref();
        bool release();

        Packet::interpreter_list::iterator appendInterpreter(Packet * p);
        Packet::interpreter_list::iterator prependInterpreter(Packet * p);
        bool releaseInterpreter(Packet * p);
        void truncateInterpreters(Packet const * p);
        void truncateInterpretersAfter(Packet const * p);

        void updateIterators(Packet::size_type index, Packet::difference_type n,
                             Packet::interpreter_list::iterator self,
                             Packet::Whence whence);

        ///////////////////////////////////////////////////////////////////////////
        // These are here to simplify the friend declaration in Packet

        static void packet_add_ref(Packet const * p);
        static void packet_release(Packet * p);
        static PacketImpl* impl(Packet const * p);
        static Packet::interpreter_list::iterator self(Packet const * p);
    };

    // These methods are used internally to keep PacketImpl_ alive during
    // method invocations
    void intrusive_ptr_add_ref(PacketImpl * p);
    void intrusive_ptr_release(PacketImpl * p);
sbund's avatar
sbund committed


struct senf::Packet::PacketOp_register
sbund's avatar
sbund committed
{
    size_type b;
    size_type e;
    const Packet * p;

    PacketOp_register(size_type b_, size_type e_, const Packet * p_)
        : b(b_), e(e_), p(p_) {}
sbund's avatar
sbund committed

    size_type begin() const { return b; }
    size_type end() const { return e; }
    void operator ()(Packet * self) const
    { p->i_registerInterpreter(self); }
};

struct senf::Packet::PacketOp_replace
sbund's avatar
sbund committed
{
    Packet * p;

    PacketOp_replace(Packet * p_) : p(p_) {}

    size_type begin() const { return p->begin_; }
    size_type end() const { return p->end_; }
    void operator()(Packet * self) const
    { p->i_replaceInterpreter(self); }
};

struct senf::Packet::PacketOp_set
sbund's avatar
sbund committed
{
    impl::PacketImpl * i;

    PacketOp_set(impl::PacketImpl * i_) : i(i_) {}

    size_type begin() const { return 0; }
    size_type end() const { return i->data_.size(); }
    void operator()(Packet * self) const
    { self->i_setInterpreter(i); }
};

///////////////////////////////ih.e////////////////////////////////////////
#endif


// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// comment-column: 40
sbund's avatar
sbund committed
// End: