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 "../Utils/pool_alloc_mixin.hh"
35 #include "PacketTypes.hh"
36 #include "../Utils/singleton.hh"
38 //#include "PacketImpl.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
43 /** \brief Marker base-class for complex annotations
45 This class is used as a base class to mark an annotation type as complex. A complex
46 annotation will have it's constructor/destructor called. Non-complex annotations will not
47 have their constructor called, they will be zero initialized. The destructor of non-complex
48 annotations is never called.
50 An annotation must be marked as complex if it is not <a
51 href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
52 annotation must be marked as ComplexAnnotation, if
54 \li it has a (user defined) constructor or destructor
55 \li it has any data members which have (user defined) constructors or destructors
57 \see \ref packet_usage_annotation
59 struct ComplexAnnotation {};
65 virtual ~AnnotationP();
68 template <class Annotation>
72 Annotation annotation;
75 union AnnotationEntry {
80 struct AnnotationIndexerBase
82 static unsigned maxAnnotations;
83 static std::vector<bool> & small();
86 template <class Annotation>
87 struct AnnotationIndexer
88 : public senf::singleton< AnnotationIndexer<Annotation> >,
89 public AnnotationIndexerBase
93 static unsigned index();
94 static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry)
95 && ! boost::is_base_of<ComplexAnnotation, Annotation>::value);
98 template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
101 static Annotation & get(AnnotationEntry & e);
104 template <class Annotation>
105 struct GetAnnotation<Annotation, true>
107 static Annotation & get(AnnotationEntry & e);
110 /** \brief Internal: Packet data storage
114 This is the class holding the packet data and the interpreter chain. All manipulations of
115 the packet data are performed via the interface exported here. This is very important, since
116 PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
120 : boost::noncopyable,
121 public pool_alloc_mixin<PacketImpl>
124 typedef senf::detail::packet::byte byte;
125 typedef senf::detail::packet::raw_container raw_container;
126 typedef senf::detail::packet::size_type size_type;
127 typedef senf::detail::packet::difference_type difference_type;
128 typedef senf::detail::packet::interpreter_list interpreter_list;
129 typedef senf::detail::packet::iterator iterator;
130 typedef senf::detail::packet::const_iterator const_iterator;
131 typedef senf::detail::packet::refcount_t refcount_t;
136 PacketImpl(size_type size, byte initValue);
137 template <class InputIterator>
138 PacketImpl(InputIterator b, InputIterator e);
141 // rerference/memory management
143 void add_ref(refcount_t n=1);
144 void release(refcount_t n=1);
145 refcount_t refcount() const;
149 PacketInterpreterBase * first();
150 PacketInterpreterBase * last();
152 PacketInterpreterBase * next(PacketInterpreterBase * p);
153 PacketInterpreterBase * prev(PacketInterpreterBase * p);
155 void appendInterpreter (PacketInterpreterBase * p);
156 void prependInterpreter (PacketInterpreterBase * p);
157 void truncateInterpreters (PacketInterpreterBase * p);
158 void truncateInterpretersBackwards (PacketInterpreterBase * p);
166 void insert(PacketData * self, iterator pos, byte v);
167 void insert(PacketData * self, iterator pos, size_type n, byte v);
168 template <class ForwardIterator>
169 void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
171 void erase(PacketData * self, iterator pos);
172 void erase(PacketData * self, iterator first, iterator last);
173 void clear(PacketData * self);
176 template <class Annotation>
177 Annotation & annotation();
179 /** \brief Internal: Keep PacketImpl instance alive
183 The Guard will keep the PacketImpl instance alive during a members execution time
184 It the refcount should drop to 0, PacketImpl will be deleted after the member
185 has completed executing.
188 Guard(PacketImpl * impl);
194 refcount_t refcount_;
196 interpreter_list interpreters_;
198 typedef std::vector<AnnotationEntry> Annotations;
199 Annotations annotations_;
201 void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
202 void updateIterators(PacketData * self, difference_type pos, difference_type n);
207 ///////////////////////////////hh.e////////////////////////////////////////
209 #if !defined(HH_Packets__decls_) && !defined(HH_PacketImpl_i_)
210 #define HH_PacketImpl_i_
211 #include "PacketImpl.cci"
212 //#include "PacketImpl.ct"
213 #include "PacketImpl.cti"
220 // c-file-style: "senf"
221 // indent-tabs-mode: nil
222 // ispell-local-dictionary: "american"
223 // compile-command: "scons -u test"
224 // comment-column: 40