// $Id$ // // Copyright (C) 2006 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) // Kompetenzzentrum fuer Satelitenkommunikation (SatCom) // 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 // 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 #define SATCOM_PKF_REFC_MSG(x) std::cerr << x #else #define SATCOM_PKF_REFC_MSG(x) #endif namespace senf { 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 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); }} struct senf::Packet::PacketOp_register { 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_) {} 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 { 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 { 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" // End: