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/static_assert.hpp>
34 #include <boost/ptr_container/ptr_vector.hpp>
35 #include <senf/Utils/pool_alloc_mixin.hh>
36 #include <senf/Utils/singleton.hh>
38 //#include "PacketImpl.mpp"
39 #include "PacketImpl.ih"
40 ///////////////////////////////hh.p////////////////////////////////////////
44 /** \brief Marker base-class for complex annotations
46 This class is used as a base class to mark an annotation type as complex. A complex
47 annotation will have it's constructor/destructor called. Non-complex annotations will not
48 have their constructor called, they will be zero initialized. The destructor of non-complex
49 annotations is never called.
51 An annotation must be marked as complex if it is not <a
52 href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
53 annotation must be marked as ComplexAnnotation, if
55 \li it has a (user defined) constructor or destructor
56 \li it has any data members which have (user defined) constructors or destructors
58 \see \ref packet_usage_annotation
60 struct ComplexAnnotation {};
62 /** \brief Dump annotation registry debug information
64 This function will dump debug information about all registered annotations to \a os. This
65 information may then be used to tune the following annotation parameters for optimal
67 \li \c SENF_PACKET_ANNOTATION_SLOTS (define, default 8) is the number of slots available for
69 \li \c SENF_PACKET_ANNOTATION_SLOTSIZE (define, default 16) is the maximum size of a fast
72 The output includes the current parameter and has the following columns:
73 \li \c NAME: Annotation type name
74 \li \c FAST: This is 'yes', if the annotation was allocated to a fast slot. Otherwise the
75 annotation is managed as a slow/complex annotation
76 \li \c COMPLEX: This is 'yes', if the annotation inherits from ComplexAnnotation
77 \li \c SIZE: Size of the annotation in bytes
79 Fast annotations are considerable faster than complex and slow annotations. However, only
80 annotations which do not need constructor or destructor calls and which may be
81 zero-initialized (on the memory level) are legible as fast annotations.
83 It is thus desirable to eliminate any complex and slow annotations, if possible. To optimize
84 the annotation system, you may take the following steps:
85 \li If there are reasonably sized non-complex annotations which are larger than the current
86 \c SENF_PACKET_ANNOTATION_SLOTSIZE value, increase this value accordingly
87 \li If there are more non-complex annotations with a size less than
88 \c SENF_PACKET_ANNOTATION_SLOTSIZE than there are available slots, increase \c
89 SENF_PACKET_ANNOTATION_SLOTS accordingly
90 \li If all fast annotations are smaller than \c SENF_PACKET_ANNOTATION_SLOTSIZE, you may
91 decrease that value accordingly
92 \li If there are fewer than \c SENF_PACKET_ANNOTATION_SLOTS fast annotations, you may
93 decrease that value accordingly
95 \see \ref packet_usage_annotation
97 void dumpPacketAnnotationRegistry(std::ostream & os);
101 /** \brief Internal: Packet data storage
105 This is the class holding the packet data and the interpreter chain. All manipulations of
106 the packet data are performed via the interface exported here. This is very important, since
107 PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
111 : boost::noncopyable,
112 public pool_alloc_mixin<PacketImpl>
115 typedef senf::detail::packet::byte byte;
116 typedef senf::detail::packet::raw_container raw_container;
117 typedef senf::detail::packet::size_type size_type;
118 typedef senf::detail::packet::difference_type difference_type;
119 typedef senf::detail::packet::interpreter_list interpreter_list;
120 typedef senf::detail::packet::iterator iterator;
121 typedef senf::detail::packet::const_iterator const_iterator;
122 typedef senf::detail::packet::refcount_t refcount_t;
127 PacketImpl(size_type size, byte initValue);
128 template <class InputIterator>
129 PacketImpl(InputIterator b, InputIterator e);
132 // rerference/memory management
134 void add_ref(refcount_t n=1);
135 void release(refcount_t n=1);
136 refcount_t refcount() const;
140 PacketInterpreterBase * first();
141 PacketInterpreterBase * last();
143 PacketInterpreterBase * next(PacketInterpreterBase * p);
144 PacketInterpreterBase * prev(PacketInterpreterBase * p);
146 void appendInterpreter (PacketInterpreterBase * p);
147 void prependInterpreter (PacketInterpreterBase * p);
148 void prependInterpreter (PacketInterpreterBase * p, PacketInterpreterBase * before);
149 void truncateInterpreters (PacketInterpreterBase * p);
150 void truncateInterpretersBackwards (PacketInterpreterBase * p);
158 void insert(PacketData * self, iterator pos, byte v);
159 void insert(PacketData * self, iterator pos, size_type n, byte v);
160 template <class ForwardIterator>
161 void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
163 void erase(PacketData * self, iterator pos);
164 void erase(PacketData * self, iterator first, iterator last);
165 void clear(PacketData * self);
167 void reserve(size_type n);
168 size_type capacity() const;
171 template <class Annotation>
172 Annotation & annotation();
174 void dumpAnnotations(std::ostream & os);
176 /** \brief Internal: Keep PacketImpl instance alive
180 The Guard will keep the PacketImpl instance alive during a members execution time
181 It the refcount should drop to 0, PacketImpl will be deleted after the member
182 has completed executing.
185 Guard(PacketImpl * impl);
191 void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
192 void updateIterators(PacketData * self, difference_type pos, difference_type n);
194 void * annotation(AnnotationRegistry::key_type key); // may return 0 !
195 void * complexAnnotation(AnnotationRegistry::key_type key); // may return 0 !
196 template <class Annotation>
197 void * complexAnnotation();
199 refcount_t refcount_;
201 interpreter_list interpreters_;
203 union SimpleAnnotationSlot
205 unsigned char _ [SENF_PACKET_ANNOTATION_SLOTSIZE];
208 typedef boost::ptr_vector< boost::nullable<AnnotationRegistry::EntryBase> >
210 ComplexAnnotations complexAnnotations_;
212 SimpleAnnotationSlot simpleAnnotations_[SENF_PACKET_ANNOTATION_SLOTS];
217 ///////////////////////////////hh.e////////////////////////////////////////
219 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketImpl_i_)
220 #define HH_SENF_Packets_PacketImpl_i_
221 #include "PacketImpl.cci"
222 #include "PacketImpl.ct"
223 #include "PacketImpl.cti"
230 // c-file-style: "senf"
231 // indent-tabs-mode: nil
232 // ispell-local-dictionary: "american"
233 // compile-command: "scons -u test"
234 // comment-column: 40