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