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_SENF_Packets_PacketImpl_
27 #define HH_SENF_Packets_PacketImpl_ 1
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 <senf/Utils/pool_alloc_mixin.hh>
38 #include <senf/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 virtual ~AnnotationIndexerBase();
85 virtual void v_dump(PacketImpl * p, std::ostream & os) = 0;
87 static unsigned maxAnnotations;
88 static std::vector<bool> & small();
89 static std::vector<AnnotationIndexerBase*> & registry();
90 static void dump(PacketImpl * p, std::ostream & os);
93 template <class Annotation>
94 struct AnnotationIndexer
95 : public senf::singleton< AnnotationIndexer<Annotation> >,
96 public AnnotationIndexerBase
99 virtual void v_dump(PacketImpl * p, std::ostream & os);
101 static unsigned index();
102 static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value;
103 static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry) && ! Complex);
105 # if 0 // The test is difficult since it does not work with user-defined trivial constructors
106 # ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS
108 BOOST_STATIC_ASSERT(( (boost::has_trivial_constructor<Annotation>::value
109 && boost::has_trivial_destructor<Annotation>::value)
116 template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
119 static Annotation & get(AnnotationEntry & e);
120 static void dump(AnnotationEntry & e, std::ostream & os);
123 template <class Annotation>
124 struct GetAnnotation<Annotation, true>
126 static Annotation & get(AnnotationEntry & e);
127 static void dump(AnnotationEntry & e, std::ostream & os);
130 /** \brief Internal: Packet data storage
134 This is the class holding the packet data and the interpreter chain. All manipulations of
135 the packet data are performed via the interface exported here. This is very important, since
136 PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
140 : boost::noncopyable,
141 public pool_alloc_mixin<PacketImpl>
144 typedef senf::detail::packet::byte byte;
145 typedef senf::detail::packet::raw_container raw_container;
146 typedef senf::detail::packet::size_type size_type;
147 typedef senf::detail::packet::difference_type difference_type;
148 typedef senf::detail::packet::interpreter_list interpreter_list;
149 typedef senf::detail::packet::iterator iterator;
150 typedef senf::detail::packet::const_iterator const_iterator;
151 typedef senf::detail::packet::refcount_t refcount_t;
156 PacketImpl(size_type size, byte initValue);
157 template <class InputIterator>
158 PacketImpl(InputIterator b, InputIterator e);
161 // rerference/memory management
163 void add_ref(refcount_t n=1);
164 void release(refcount_t n=1);
165 refcount_t refcount() const;
169 PacketInterpreterBase * first();
170 PacketInterpreterBase * last();
172 PacketInterpreterBase * next(PacketInterpreterBase * p);
173 PacketInterpreterBase * prev(PacketInterpreterBase * p);
175 void appendInterpreter (PacketInterpreterBase * p);
176 void prependInterpreter (PacketInterpreterBase * p);
177 void truncateInterpreters (PacketInterpreterBase * p);
178 void truncateInterpretersBackwards (PacketInterpreterBase * p);
186 void insert(PacketData * self, iterator pos, byte v);
187 void insert(PacketData * self, iterator pos, size_type n, byte v);
188 template <class ForwardIterator>
189 void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
191 void erase(PacketData * self, iterator pos);
192 void erase(PacketData * self, iterator first, iterator last);
193 void clear(PacketData * self);
195 void reserve(size_type n);
196 size_type capacity() const;
199 template <class Annotation>
200 Annotation & annotation();
201 void dumpAnnotations(std::ostream & os);
202 template <class Annotation>
203 void dumpAnnotation(std::ostream & os);
205 /** \brief Internal: Keep PacketImpl instance alive
209 The Guard will keep the PacketImpl instance alive during a members execution time
210 It the refcount should drop to 0, PacketImpl will be deleted after the member
211 has completed executing.
214 Guard(PacketImpl * impl);
220 refcount_t refcount_;
222 interpreter_list interpreters_;
224 typedef std::vector<AnnotationEntry> Annotations;
225 Annotations annotations_;
227 void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
228 void updateIterators(PacketData * self, difference_type pos, difference_type n);
233 ///////////////////////////////hh.e////////////////////////////////////////
235 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketImpl_i_)
236 #define HH_SENF_Packets_PacketImpl_i_
237 #include "PacketImpl.cci"
238 //#include "PacketImpl.ct"
239 #include "PacketImpl.cti"
246 // c-file-style: "senf"
247 // indent-tabs-mode: nil
248 // ispell-local-dictionary: "american"
249 // compile-command: "scons -u test"
250 // comment-column: 40