4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief PacketImpl public header */
26 #ifndef HH_PacketImpl_
27 #define HH_PacketImpl_ 1
32 #include <boost/utility.hpp>
33 #include <boost/type_traits/is_base_of.hpp>
34 #include <boost/type_traits/is_pod.hpp>
35 #include <boost/static_assert.hpp>
36 #include "../Utils/pool_alloc_mixin.hh"
37 #include "PacketTypes.hh"
38 #include "../Utils/singleton.hh"
40 //#include "PacketImpl.mpp"
41 ///////////////////////////////hh.p////////////////////////////////////////
45 /** \brief Marker base-class for complex annotations
47 This class is used as a base class to mark an annotation type as complex. A complex
48 annotation will have it's constructor/destructor called. Non-complex annotations will not
49 have their constructor called, they will be zero initialized. The destructor of non-complex
50 annotations is never called.
52 An annotation must be marked as complex if it is not <a
53 href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
54 annotation must be marked as ComplexAnnotation, if
56 \li it has a (user defined) constructor or destructor
57 \li it has any data members which have (user defined) constructors or destructors
59 \see \ref packet_usage_annotation
61 struct ComplexAnnotation {};
67 virtual ~AnnotationP();
70 template <class Annotation>
74 Annotation annotation;
77 union AnnotationEntry {
82 struct AnnotationIndexerBase
84 static unsigned maxAnnotations;
85 static std::vector<bool> & small();
88 template <class Annotation>
89 struct AnnotationIndexer
90 : public senf::singleton< AnnotationIndexer<Annotation> >,
91 public AnnotationIndexerBase
95 static unsigned index();
96 static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value;
97 static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry) && ! Complex);
99 # ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS
101 BOOST_STATIC_ASSERT(( boost::is_pod<Annotation>::value || Complex ));
106 template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
109 static Annotation & get(AnnotationEntry & e);
112 template <class Annotation>
113 struct GetAnnotation<Annotation, true>
115 static Annotation & get(AnnotationEntry & e);
118 /** \brief Internal: Packet data storage
122 This is the class holding the packet data and the interpreter chain. All manipulations of
123 the packet data are performed via the interface exported here. This is very important, since
124 PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
128 : boost::noncopyable,
129 public pool_alloc_mixin<PacketImpl>
132 typedef senf::detail::packet::byte byte;
133 typedef senf::detail::packet::raw_container raw_container;
134 typedef senf::detail::packet::size_type size_type;
135 typedef senf::detail::packet::difference_type difference_type;
136 typedef senf::detail::packet::interpreter_list interpreter_list;
137 typedef senf::detail::packet::iterator iterator;
138 typedef senf::detail::packet::const_iterator const_iterator;
139 typedef senf::detail::packet::refcount_t refcount_t;
144 PacketImpl(size_type size, byte initValue);
145 template <class InputIterator>
146 PacketImpl(InputIterator b, InputIterator e);
149 // rerference/memory management
151 void add_ref(refcount_t n=1);
152 void release(refcount_t n=1);
153 refcount_t refcount() const;
157 PacketInterpreterBase * first();
158 PacketInterpreterBase * last();
160 PacketInterpreterBase * next(PacketInterpreterBase * p);
161 PacketInterpreterBase * prev(PacketInterpreterBase * p);
163 void appendInterpreter (PacketInterpreterBase * p);
164 void prependInterpreter (PacketInterpreterBase * p);
165 void truncateInterpreters (PacketInterpreterBase * p);
166 void truncateInterpretersBackwards (PacketInterpreterBase * p);
174 void insert(PacketData * self, iterator pos, byte v);
175 void insert(PacketData * self, iterator pos, size_type n, byte v);
176 template <class ForwardIterator>
177 void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
179 void erase(PacketData * self, iterator pos);
180 void erase(PacketData * self, iterator first, iterator last);
181 void clear(PacketData * self);
184 template <class Annotation>
185 Annotation & annotation();
187 /** \brief Internal: Keep PacketImpl instance alive
191 The Guard will keep the PacketImpl instance alive during a members execution time
192 It the refcount should drop to 0, PacketImpl will be deleted after the member
193 has completed executing.
196 Guard(PacketImpl * impl);
202 refcount_t refcount_;
204 interpreter_list interpreters_;
206 typedef std::vector<AnnotationEntry> Annotations;
207 Annotations annotations_;
209 void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
210 void updateIterators(PacketData * self, difference_type pos, difference_type n);
215 ///////////////////////////////hh.e////////////////////////////////////////
217 #if !defined(HH_Packets__decls_) && !defined(HH_PacketImpl_i_)
218 #define HH_PacketImpl_i_
219 #include "PacketImpl.cci"
220 //#include "PacketImpl.ct"
221 #include "PacketImpl.cti"
228 // c-file-style: "senf"
229 // indent-tabs-mode: nil
230 // ispell-local-dictionary: "american"
231 // compile-command: "scons -u test"
232 // comment-column: 40