550145c080992a0b467d6707f442e1e4a1afaf6b
[senf.git] / Packets / Packet.ih
1 // $Id$
2 //
3 // Copyright (C) 2006 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 #ifndef IH_Packet_
24 #define IH_Packet_ 1
25
26 // Custom includes
27
28 ///////////////////////////////ih.p////////////////////////////////////////
29
30 #ifdef SATCOM_PKF_REFC_DEBUG
31 #include <iostream>
32 #define SATCOM_PKF_REFC_MSG(x) std::cerr << x
33 #else
34 #define SATCOM_PKF_REFC_MSG(x)
35 #endif
36
37 namespace senf {
38
39 namespace impl {
40
41     // This deleter is used in the PacketImpl list holding the
42     // Packet's. It only decrements the Packet refcount. If this
43     // drops to 0 (i.e. the packet is removed from the list and no
44     // external reference exists) the packet ist deleted.
45     //
46     // Since this is called, when the packet is removed from the
47     // list, we set the impl_ member to 0 to mark, that the packet
48     // is now orphaned and every use should throw an exception ...
49     //
50     // To make this work we must make sure, that the packet
51     // refcount is incremented when we add the packet to the list.
52     struct ListPacketDeleter {
53         void operator()(Packet * p);
54     };
55
56     struct PacketImpl
57     {
58         Packet::raw_container data_;
59         Packet::interpreter_list interpreters_;
60         Packet::refcount_t refcount_;
61
62         PacketImpl();
63         PacketImpl(unsigned size, Packet::byte initValue);
64         ~PacketImpl();
65         template <class InputIterator>
66         PacketImpl(InputIterator begin, InputIterator end);
67
68         void add_ref();
69         bool release();
70
71         Packet::interpreter_list::iterator appendInterpreter(Packet * p);
72         Packet::interpreter_list::iterator prependInterpreter(Packet * p);
73         bool releaseInterpreter(Packet * p);
74         void truncateInterpreters(Packet const * p);
75         void truncateInterpretersAfter(Packet const * p);
76
77         void updateIterators(Packet::size_type index, Packet::difference_type n,
78                              Packet::interpreter_list::iterator self,
79                              Packet::Whence whence);
80
81         ///////////////////////////////////////////////////////////////////////////
82         // These are here to simplify the friend declaration in Packet
83
84         static void packet_add_ref(Packet const * p);
85         static void packet_release(Packet * p);
86         static PacketImpl* impl(Packet const * p);
87         static Packet::interpreter_list::iterator self(Packet const * p);
88     };
89
90     // These methods are used internally to keep PacketImpl_ alive during
91     // method invocations
92     void intrusive_ptr_add_ref(PacketImpl * p);
93     void intrusive_ptr_release(PacketImpl * p);
94 }}
95
96
97 struct senf::Packet::PacketOp_register
98 {
99     size_type b;
100     size_type e;
101     const Packet * p;
102
103     PacketOp_register(size_type b_, size_type e_, const Packet * p_) 
104         : b(b_), e(e_), p(p_) {}
105
106     size_type begin() const { return b; }
107     size_type end() const { return e; }
108     void operator ()(Packet * self) const
109     { p->i_registerInterpreter(self); }
110 };
111
112 struct senf::Packet::PacketOp_replace 
113 {
114     Packet * p;
115
116     PacketOp_replace(Packet * p_) : p(p_) {}
117
118     size_type begin() const { return p->begin_; }
119     size_type end() const { return p->end_; }
120     void operator()(Packet * self) const
121     { p->i_replaceInterpreter(self); }
122 };
123
124 struct senf::Packet::PacketOp_set
125 {
126     impl::PacketImpl * i;
127
128     PacketOp_set(impl::PacketImpl * i_) : i(i_) {}
129
130     size_type begin() const { return 0; }
131     size_type end() const { return i->data_.size(); }
132     void operator()(Packet * self) const
133     { self->i_setInterpreter(i); }
134 };
135
136 ///////////////////////////////ih.e////////////////////////////////////////
137 #endif
138
139 \f
140 // Local Variables:
141 // mode: c++
142 // c-file-style: "senf"
143 // End: