92738a46277fe02446ebb17740e96c600867fb54
[senf.git] / 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_PacketImpl_
27 #define HH_PacketImpl_ 1
28
29 // Custom includes
30 #include <memory>
31 #include <vector>
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"
37
38 //#include "PacketImpl.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42
43     struct ComplexAnnotation {};
44
45 namespace detail {
46
47     struct AnnotationP
48     {
49         virtual ~AnnotationP();
50     };
51
52     template <class Annotation>
53     struct TAnnotationP
54         : public AnnotationP
55     {
56         Annotation annotation;
57     };
58
59     union AnnotationEntry {
60         AnnotationP * p;
61         unsigned long long i;
62     };
63
64     struct AnnotationIndexerBase
65     {
66         static unsigned maxAnnotations;
67         static std::vector<bool> & small();
68     };
69
70     template <class Annotation>
71     struct AnnotationIndexer 
72         : public senf::singleton< AnnotationIndexer<Annotation> >, 
73           public AnnotationIndexerBase
74     {
75         AnnotationIndexer();
76         unsigned index_;
77         static unsigned index();
78         static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry) 
79                                    && ! boost::is_base_of<ComplexAnnotation, Annotation>::value);
80     };
81
82     template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
83     struct GetAnnotation
84     {
85         static Annotation & get(AnnotationEntry & e);
86     };
87
88     template <class Annotation>
89     struct GetAnnotation<Annotation, true>
90     {
91         static Annotation & get(AnnotationEntry & e);
92     };
93
94     /** \brief Internal: Packet data storage
95
96         \internal
97
98         This is the class holding the packet data and the interpreter chain. All manipulations of
99         the packet data are performed via the interface exported here. This is very important, since
100         PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
101         the data is changed.
102      */
103     class PacketImpl
104         : boost::noncopyable,
105           public pool_alloc_mixin<PacketImpl>
106     {
107     public:
108         typedef senf::detail::packet::byte byte;
109         typedef senf::detail::packet::raw_container raw_container;
110         typedef senf::detail::packet::size_type size_type;
111         typedef senf::detail::packet::difference_type difference_type;
112         typedef senf::detail::packet::interpreter_list interpreter_list;
113         typedef senf::detail::packet::iterator iterator;
114         typedef senf::detail::packet::const_iterator const_iterator;
115         typedef senf::detail::packet::refcount_t refcount_t;
116
117         // structors
118
119         PacketImpl();
120         PacketImpl(size_type size, byte initValue);
121         template <class InputIterator>
122         PacketImpl(InputIterator b, InputIterator e);
123         ~PacketImpl();
124
125         // rerference/memory management
126
127         void add_ref(refcount_t n=1);
128         void release(refcount_t n=1);
129         refcount_t refcount() const;
130
131         // Interpreter chain
132
133         PacketInterpreterBase * first();
134         PacketInterpreterBase * last();
135
136         PacketInterpreterBase * next(PacketInterpreterBase * p);
137         PacketInterpreterBase * prev(PacketInterpreterBase * p);
138
139         void appendInterpreter    (PacketInterpreterBase * p);
140         void prependInterpreter   (PacketInterpreterBase * p);
141         void truncateInterpreters (PacketInterpreterBase * p);
142         void truncateInterpretersBackwards (PacketInterpreterBase * p);
143
144         // Data container
145
146         iterator begin();
147         iterator end();
148         size_type size();
149
150         void insert(PacketData * self, iterator pos, byte v);
151         void insert(PacketData * self, iterator pos, size_type n, byte v);
152         template <class ForwardIterator>
153         void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
154
155         void erase(PacketData * self, iterator pos);
156         void erase(PacketData * self, iterator first, iterator last);
157         void clear(PacketData * self);
158
159         // Annotations
160         template <class Annotation>
161         Annotation & annotation();
162
163         /** \brief Internal: Keep PacketImpl instance alive
164
165             \internal
166
167             The Guard will keep the PacketImpl instance alive during a members execution time
168             It the refcount should drop to 0, PacketImpl will be deleted after the member
169             has completed executing.
170          */
171         struct Guard {
172             Guard(PacketImpl * impl);
173             ~Guard();
174             PacketImpl * p;
175         };
176
177     private:
178         refcount_t refcount_;
179         raw_container data_;
180         interpreter_list interpreters_;
181         
182         typedef std::vector<AnnotationEntry> Annotations;
183         Annotations annotations_;
184
185         void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
186         void updateIterators(PacketData * self, difference_type pos, difference_type n);
187     };
188
189 }}
190
191 ///////////////////////////////hh.e////////////////////////////////////////
192 #endif
193 #if !defined(HH_Packets__decls_) && !defined(HH_PacketImpl_i_)
194 #define HH_PacketImpl_i_
195 #include "PacketImpl.cci"
196 //#include "PacketImpl.ct"
197 #include "PacketImpl.cti"
198 #endif
199
200 \f
201 // Local Variables:
202 // mode: c++
203 // fill-column: 100
204 // c-file-style: "senf"
205 // indent-tabs-mode: nil
206 // ispell-local-dictionary: "american"
207 // compile-command: "scons -u test"
208 // comment-column: 40
209 // End:
210