4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief PacketImpl public header */
31 #ifndef HH_SENF_Packets_PacketImpl_
32 #define HH_SENF_Packets_PacketImpl_ 1
37 #include <boost/utility.hpp>
38 #include <boost/static_assert.hpp>
39 #include <boost/ptr_container/ptr_vector.hpp>
40 #include <senf/Utils/pool_alloc_mixin.hh>
41 #include <senf/Utils/singleton.hh>
43 //#include "PacketImpl.mpp"
44 #include "PacketImpl.ih"
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
49 /** \brief Marker base-class for complex annotations
51 This class is used as a base class to mark an annotation type as complex. A complex
52 annotation will have it's constructor/destructor called. Non-complex annotations will not
53 have their constructor called, they will be zero initialized. The destructor of non-complex
54 annotations is never called.
56 An annotation must be marked as complex if it is not <a
57 href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
58 annotation must be marked as ComplexAnnotation, if
60 \li it has a (user defined) constructor or destructor
61 \li it has any data members which have (user defined) constructors or destructors
63 \see \ref packet_usage_annotation
65 struct ComplexAnnotation {};
67 /** \brief Dump annotation registry debug information
69 This function will dump debug information about all registered annotations to \a os. This
70 information may then be used to tune the following annotation parameters for optimal
72 \li \c SENF_PACKET_ANNOTATION_SLOTS (define, default 8) is the number of slots available for
74 \li \c SENF_PACKET_ANNOTATION_SLOTSIZE (define, default 16) is the maximum size of a fast
77 The output includes the current parameter and has the following columns:
78 \li \c NAME: Annotation type name
79 \li \c FAST: This is 'yes', if the annotation was allocated to a fast slot. Otherwise the
80 annotation is managed as a slow/complex annotation
81 \li \c COMPLEX: This is 'yes', if the annotation inherits from ComplexAnnotation
82 \li \c SIZE: Size of the annotation in bytes
84 Fast annotations are considerable faster than complex and slow annotations. However, only
85 annotations which do not need constructor or destructor calls and which may be
86 zero-initialized (on the memory level) are legible as fast annotations.
88 It is thus desirable to eliminate any complex and slow annotations, if possible. To optimize
89 the annotation system, you may take the following steps:
90 \li If there are reasonably sized non-complex annotations which are larger than the current
91 \c SENF_PACKET_ANNOTATION_SLOTSIZE value, increase this value accordingly
92 \li If there are more non-complex annotations with a size less than
93 \c SENF_PACKET_ANNOTATION_SLOTSIZE than there are available slots, increase \c
94 SENF_PACKET_ANNOTATION_SLOTS accordingly
95 \li If all fast annotations are smaller than \c SENF_PACKET_ANNOTATION_SLOTSIZE, you may
96 decrease that value accordingly
97 \li If there are fewer than \c SENF_PACKET_ANNOTATION_SLOTS fast annotations, you may
98 decrease that value accordingly
100 \see \ref packet_usage_annotation
102 void dumpPacketAnnotationRegistry(std::ostream & os);
106 /** \brief Internal: Packet data storage
110 This is the class holding the packet data and the interpreter chain. All manipulations of
111 the packet data are performed via the interface exported here. This is very important, since
112 PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
116 : boost::noncopyable,
117 public pool_alloc_mixin<PacketImpl>
120 typedef senf::detail::packet::byte byte;
121 typedef senf::detail::packet::raw_container raw_container;
122 typedef senf::detail::packet::size_type size_type;
123 typedef senf::detail::packet::difference_type difference_type;
124 typedef senf::detail::packet::interpreter_list interpreter_list;
125 typedef senf::detail::packet::iterator iterator;
126 typedef senf::detail::packet::const_iterator const_iterator;
127 typedef senf::detail::packet::refcount_t refcount_t;
132 PacketImpl(size_type size, byte initValue);
133 template <class InputIterator>
134 PacketImpl(InputIterator b, InputIterator e);
137 // rerference/memory management
141 refcount_t refcount() const;
145 PacketInterpreterBase * first();
146 PacketInterpreterBase * last();
148 PacketInterpreterBase * next(PacketInterpreterBase * p);
149 PacketInterpreterBase * prev(PacketInterpreterBase * p);
151 void appendInterpreter (PacketInterpreterBase * p);
152 void prependInterpreter (PacketInterpreterBase * p);
153 void prependInterpreter (PacketInterpreterBase * p, PacketInterpreterBase * before);
154 void truncateInterpreters (PacketInterpreterBase * p);
155 void truncateInterpretersBackwards (PacketInterpreterBase * p);
163 void insert(PacketData * self, iterator pos, byte v);
164 void insert(PacketData * self, iterator pos, size_type n, byte v);
165 template <class ForwardIterator>
166 void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
168 void erase(PacketData * self, iterator pos);
169 void erase(PacketData * self, iterator first, iterator last);
170 void clear(PacketData * self);
172 void reserve(size_type n);
173 size_type capacity() const;
176 template <class Annotation>
177 Annotation & annotation();
179 void clearAnnotations();
180 void assignAnnotations(PacketImpl const & other);
181 void dumpAnnotations(std::ostream & os);
183 /** \brief Internal: Keep PacketImpl instance alive
187 The Guard will keep the PacketImpl instance alive during a members execution time
188 If the refcount should drop to 0, PacketImpl will be deleted after the member
189 has completed executing.
192 Guard(PacketImpl * impl);
198 void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
199 void updateIterators(PacketData * self, difference_type pos, difference_type n);
201 void * annotation(AnnotationRegistry::key_type key); // may return 0 !
202 void * complexAnnotation(AnnotationRegistry::key_type key); // may return 0 !
203 template <class Annotation>
204 void * complexAnnotation();
206 refcount_t refcount_;
208 interpreter_list interpreters_;
210 union SimpleAnnotationSlot
212 unsigned char _ [SENF_PACKET_ANNOTATION_SLOTSIZE];
215 typedef boost::ptr_vector< boost::nullable<AnnotationRegistry::EntryBase> >
217 ComplexAnnotations complexAnnotations_;
219 SimpleAnnotationSlot simpleAnnotations_[SENF_PACKET_ANNOTATION_SLOTS];
224 //-/////////////////////////////////////////////////////////////////////////////////////////////////
226 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketImpl_i_)
227 #define HH_SENF_Packets_PacketImpl_i_
228 #include "PacketImpl.cci"
229 #include "PacketImpl.ct"
230 #include "PacketImpl.cti"
237 // c-file-style: "senf"
238 // indent-tabs-mode: nil
239 // ispell-local-dictionary: "american"
240 // compile-command: "scons -u test"
241 // comment-column: 40