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 "PacketTypes.hh"
39 #include <senf/Utils/singleton.hh>
41 //#include "PacketImpl.mpp"
42 ///////////////////////////////hh.p////////////////////////////////////////
46 /** \brief Marker base-class for complex annotations
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.
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
57 \li it has a (user defined) constructor or destructor
58 \li it has any data members which have (user defined) constructors or destructors
60 \see \ref packet_usage_annotation
62 struct ComplexAnnotation {};
68 virtual ~AnnotationP();
71 template <class Annotation>
75 Annotation annotation;
78 union AnnotationEntry {
83 struct AnnotationIndexerBase
85 virtual ~AnnotationIndexerBase();
86 virtual void v_dump(PacketImpl * p, std::ostream & os) = 0;
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);
94 template <class Annotation>
95 struct AnnotationIndexer
96 : public senf::singleton< AnnotationIndexer<Annotation> >,
97 public AnnotationIndexerBase
100 virtual void v_dump(PacketImpl * p, std::ostream & os);
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);
106 # if 0 // The test is difficult since it does not work with user-defined trivial constructors
107 # ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS
109 BOOST_STATIC_ASSERT(( (boost::has_trivial_constructor<Annotation>::value
110 && boost::has_trivial_destructor<Annotation>::value)
117 template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
120 static Annotation & get(AnnotationEntry & e);
121 static void dump(AnnotationEntry & e, std::ostream & os);
124 template <class Annotation>
125 struct GetAnnotation<Annotation, true>
127 static Annotation & get(AnnotationEntry & e);
128 static void dump(AnnotationEntry & e, std::ostream & os);
131 /** \brief Internal: Packet data storage
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
141 : boost::noncopyable,
142 public pool_alloc_mixin<PacketImpl>
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;
157 PacketImpl(size_type size, byte initValue);
158 template <class InputIterator>
159 PacketImpl(InputIterator b, InputIterator e);
162 // rerference/memory management
164 void add_ref(refcount_t n=1);
165 void release(refcount_t n=1);
166 refcount_t refcount() const;
170 PacketInterpreterBase * first();
171 PacketInterpreterBase * last();
173 PacketInterpreterBase * next(PacketInterpreterBase * p);
174 PacketInterpreterBase * prev(PacketInterpreterBase * p);
176 void appendInterpreter (PacketInterpreterBase * p);
177 void prependInterpreter (PacketInterpreterBase * p);
178 void truncateInterpreters (PacketInterpreterBase * p);
179 void truncateInterpretersBackwards (PacketInterpreterBase * p);
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);
192 void erase(PacketData * self, iterator pos);
193 void erase(PacketData * self, iterator first, iterator last);
194 void clear(PacketData * self);
196 void reserve(size_type n);
197 size_type capacity() const;
200 template <class Annotation>
201 Annotation & annotation();
202 void dumpAnnotations(std::ostream & os);
203 template <class Annotation>
204 void dumpAnnotation(std::ostream & os);
206 /** \brief Internal: Keep PacketImpl instance alive
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.
215 Guard(PacketImpl * impl);
221 refcount_t refcount_;
223 interpreter_list interpreters_;
225 typedef std::vector<AnnotationEntry> Annotations;
226 Annotations annotations_;
228 void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
229 void updateIterators(PacketData * self, difference_type pos, difference_type n);
234 ///////////////////////////////hh.e////////////////////////////////////////
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"
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