Packets: Keep annotation registry sorted by type name
[senf.git] / senf / Packets / PacketImpl.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief PacketImpl public header */
25
26 #ifndef HH_SENF_Packets_PacketImpl_
27 #define HH_SENF_Packets_PacketImpl_ 1
28
29 // Custom includes
30 #include <memory>
31 #include <vector>
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>
37
38 //#include "PacketImpl.mpp"
39 #include "PacketImpl.ih"
40 ///////////////////////////////hh.p////////////////////////////////////////
41
42 namespace senf {
43
44     /** \brief Marker base-class for complex annotations
45
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.
50
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
54
55         \li it has a (user defined) constructor or destructor
56         \li it has any data members which have (user defined) constructors or destructors
57
58         \see \ref packet_usage_annotation
59      */
60     struct ComplexAnnotation {};
61
62 namespace detail {
63
64     /** \brief Internal: Packet data storage
65
66         \internal
67
68         This is the class holding the packet data and the interpreter chain. All manipulations of
69         the packet data are performed via the interface exported here. This is very important, since
70         PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
71         the data is changed.
72      */
73     class PacketImpl
74         : boost::noncopyable,
75           public pool_alloc_mixin<PacketImpl>
76     {
77     public:
78         typedef senf::detail::packet::byte byte;
79         typedef senf::detail::packet::raw_container raw_container;
80         typedef senf::detail::packet::size_type size_type;
81         typedef senf::detail::packet::difference_type difference_type;
82         typedef senf::detail::packet::interpreter_list interpreter_list;
83         typedef senf::detail::packet::iterator iterator;
84         typedef senf::detail::packet::const_iterator const_iterator;
85         typedef senf::detail::packet::refcount_t refcount_t;
86
87         // structors
88
89         PacketImpl();
90         PacketImpl(size_type size, byte initValue);
91         template <class InputIterator>
92         PacketImpl(InputIterator b, InputIterator e);
93         ~PacketImpl();
94
95         // rerference/memory management
96
97         void add_ref(refcount_t n=1);
98         void release(refcount_t n=1);
99         refcount_t refcount() const;
100
101         // Interpreter chain
102
103         PacketInterpreterBase * first();
104         PacketInterpreterBase * last();
105
106         PacketInterpreterBase * next(PacketInterpreterBase * p);
107         PacketInterpreterBase * prev(PacketInterpreterBase * p);
108
109         void appendInterpreter    (PacketInterpreterBase * p);
110         void prependInterpreter   (PacketInterpreterBase * p);
111         void prependInterpreter   (PacketInterpreterBase * p, PacketInterpreterBase * before);
112         void truncateInterpreters (PacketInterpreterBase * p);
113         void truncateInterpretersBackwards (PacketInterpreterBase * p);
114
115         // Data container
116
117         iterator begin();
118         iterator end();
119         size_type size();
120
121         void insert(PacketData * self, iterator pos, byte v);
122         void insert(PacketData * self, iterator pos, size_type n, byte v);
123         template <class ForwardIterator>
124         void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
125
126         void erase(PacketData * self, iterator pos);
127         void erase(PacketData * self, iterator first, iterator last);
128         void clear(PacketData * self);
129
130         void reserve(size_type n);
131         size_type capacity() const;
132
133         // Annotations
134         template <class Annotation>
135         Annotation & annotation();
136
137         void dumpAnnotations(std::ostream & os);
138
139         /** \brief Internal: Keep PacketImpl instance alive
140
141             \internal
142
143             The Guard will keep the PacketImpl instance alive during a members execution time
144             It the refcount should drop to 0, PacketImpl will be deleted after the member
145             has completed executing.
146          */
147         struct Guard {
148             Guard(PacketImpl * impl);
149             ~Guard();
150             PacketImpl * p;
151         };
152
153     private:
154         void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
155         void updateIterators(PacketData * self, difference_type pos, difference_type n);
156
157         void * annotation(AnnotationRegistry::key_type key); // may return 0 !
158         void * complexAnnotation(AnnotationRegistry::key_type key); // may return 0 !
159         template <class Annotation>
160         void * complexAnnotation();
161
162         refcount_t refcount_;
163         raw_container data_;
164         interpreter_list interpreters_;
165
166         union SimpleAnnotationSlot
167         {
168             unsigned char _ [SENF_PACKET_ANNOTATION_SLOTSIZE];
169         };
170
171         typedef boost::ptr_vector< boost::nullable<AnnotationRegistry::EntryBase> >
172             ComplexAnnotations;
173 #       ifndef SENF_PACKET_NO_COMPLEX_ANNOTATIONS
174             ComplexAnnotations complexAnnotations_;
175 #       endif
176
177         SimpleAnnotationSlot simpleAnnotations_[SENF_PACKET_ANNOTATION_SLOTS];
178     };
179
180 }}
181
182 ///////////////////////////////hh.e////////////////////////////////////////
183 #endif
184 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketImpl_i_)
185 #define HH_SENF_Packets_PacketImpl_i_
186 #include "PacketImpl.cci"
187 #include "PacketImpl.ct"
188 #include "PacketImpl.cti"
189 #endif
190
191 \f
192 // Local Variables:
193 // mode: c++
194 // fill-column: 100
195 // c-file-style: "senf"
196 // indent-tabs-mode: nil
197 // ispell-local-dictionary: "american"
198 // compile-command: "scons -u test"
199 // comment-column: 40
200 // End: