4aa2d8c1f63065a5963c48fe893304743532f326
[senf.git] / Packets / PacketImpl.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.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 /** \file
24     \brief PacketImpl public header */
25
26 #ifndef HH_PacketImpl_
27 #define HH_PacketImpl_ 1
28
29 // Custom includes
30 #include <memory>
31 #include <vector>
32 #include <boost/utility.hpp>
33 #include <boost/type_traits/is_base_of.hpp>
34 #include "../Utils/pool_alloc_mixin.hh"
35 #include "PacketTypes.hh"
36 #include "../Utils/singleton.hh"
37
38 //#include "PacketImpl.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42
43     /** \brief Marker base-class for complex annotations
44
45         This class is used as a base class to mark an annotation type as complex. A complex
46         annotation will have it's constructor/destructor called. Non-complex annotations will not
47         have their constructor called, they will be zero initialized. The destructor of non-complex
48         annotations is never called.
49
50         An annotation must be marked as complex if it is not <a
51         href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
52         annotation must be marked as ComplexAnnotation, if
53
54         \li it has a (user defined) constructor or destructor
55         \li it has any data members which have (user defined) constructors or destructors
56
57         \see \ref packet_usage_annotation
58      */
59     struct ComplexAnnotation {};
60
61 namespace detail {
62
63     struct AnnotationP
64     {
65         virtual ~AnnotationP();
66     };
67
68     template <class Annotation>
69     struct TAnnotationP
70         : public AnnotationP
71     {
72         Annotation annotation;
73     };
74
75     union AnnotationEntry {
76         AnnotationP * p;
77         unsigned long long i;
78     };
79
80     struct AnnotationIndexerBase
81     {
82         static unsigned maxAnnotations;
83         static std::vector<bool> & small();
84     };
85
86     template <class Annotation>
87     struct AnnotationIndexer 
88         : public senf::singleton< AnnotationIndexer<Annotation> >, 
89           public AnnotationIndexerBase
90     {
91         AnnotationIndexer();
92         unsigned index_;
93         static unsigned index();
94         static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry) 
95                                    && ! boost::is_base_of<ComplexAnnotation, Annotation>::value);
96     };
97
98     template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
99     struct GetAnnotation
100     {
101         static Annotation & get(AnnotationEntry & e);
102     };
103
104     template <class Annotation>
105     struct GetAnnotation<Annotation, true>
106     {
107         static Annotation & get(AnnotationEntry & e);
108     };
109
110     /** \brief Internal: Packet data storage
111
112         \internal
113
114         This is the class holding the packet data and the interpreter chain. All manipulations of
115         the packet data are performed via the interface exported here. This is very important, since
116         PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
117         the data is changed.
118      */
119     class PacketImpl
120         : boost::noncopyable,
121           public pool_alloc_mixin<PacketImpl>
122     {
123     public:
124         typedef senf::detail::packet::byte byte;
125         typedef senf::detail::packet::raw_container raw_container;
126         typedef senf::detail::packet::size_type size_type;
127         typedef senf::detail::packet::difference_type difference_type;
128         typedef senf::detail::packet::interpreter_list interpreter_list;
129         typedef senf::detail::packet::iterator iterator;
130         typedef senf::detail::packet::const_iterator const_iterator;
131         typedef senf::detail::packet::refcount_t refcount_t;
132
133         // structors
134
135         PacketImpl();
136         PacketImpl(size_type size, byte initValue);
137         template <class InputIterator>
138         PacketImpl(InputIterator b, InputIterator e);
139         ~PacketImpl();
140
141         // rerference/memory management
142
143         void add_ref(refcount_t n=1);
144         void release(refcount_t n=1);
145         refcount_t refcount() const;
146
147         // Interpreter chain
148
149         PacketInterpreterBase * first();
150         PacketInterpreterBase * last();
151
152         PacketInterpreterBase * next(PacketInterpreterBase * p);
153         PacketInterpreterBase * prev(PacketInterpreterBase * p);
154
155         void appendInterpreter    (PacketInterpreterBase * p);
156         void prependInterpreter   (PacketInterpreterBase * p);
157         void truncateInterpreters (PacketInterpreterBase * p);
158         void truncateInterpretersBackwards (PacketInterpreterBase * p);
159
160         // Data container
161
162         iterator begin();
163         iterator end();
164         size_type size();
165
166         void insert(PacketData * self, iterator pos, byte v);
167         void insert(PacketData * self, iterator pos, size_type n, byte v);
168         template <class ForwardIterator>
169         void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
170
171         void erase(PacketData * self, iterator pos);
172         void erase(PacketData * self, iterator first, iterator last);
173         void clear(PacketData * self);
174
175         // Annotations
176         template <class Annotation>
177         Annotation & annotation();
178
179         /** \brief Internal: Keep PacketImpl instance alive
180
181             \internal
182
183             The Guard will keep the PacketImpl instance alive during a members execution time
184             It the refcount should drop to 0, PacketImpl will be deleted after the member
185             has completed executing.
186          */
187         struct Guard {
188             Guard(PacketImpl * impl);
189             ~Guard();
190             PacketImpl * p;
191         };
192
193     private:
194         refcount_t refcount_;
195         raw_container data_;
196         interpreter_list interpreters_;
197         
198         typedef std::vector<AnnotationEntry> Annotations;
199         Annotations annotations_;
200
201         void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
202         void updateIterators(PacketData * self, difference_type pos, difference_type n);
203     };
204
205 }}
206
207 ///////////////////////////////hh.e////////////////////////////////////////
208 #endif
209 #if !defined(HH_Packets__decls_) && !defined(HH_PacketImpl_i_)
210 #define HH_PacketImpl_i_
211 #include "PacketImpl.cci"
212 //#include "PacketImpl.ct"
213 #include "PacketImpl.cti"
214 #endif
215
216 \f
217 // Local Variables:
218 // mode: c++
219 // fill-column: 100
220 // c-file-style: "senf"
221 // indent-tabs-mode: nil
222 // ispell-local-dictionary: "american"
223 // compile-command: "scons -u test"
224 // comment-column: 40
225 // End:
226