Packets: Completely restructured #includes, introduced central Packets.hh file
[senf.git] / Packets / PacketData.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.de>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief PacketData public header */
23
24 #ifndef HH_PacketData_
25 #define HH_PacketData_ 1
26
27 // Custom includes
28 #include <boost/utility.hpp>
29 #include <boost/type_traits.hpp>
30 #include <boost/iterator/iterator_facade.hpp>
31 #include "Utils/SafeBool.hh"
32 #include "PacketTypes.hh"
33
34 //#include "PacketData.mpp"
35 ///////////////////////////////hh.p////////////////////////////////////////
36
37 namespace senf {
38
39     /** \brief Packet data STL-sequence view
40
41         The PacketData class provides an STL-sequence compatible view of the raw packet data. Each
42         packet/header/interpreter in the chain references the same storage area, presenting a
43         different (but nested/overlapping) section of the data.
44
45         Whenever the data is manipulated through PacketData, the change is assumed to be within the
46         data range of that packet: All insertions take place \e inside \c this packet and \e outside
47         any following packets in the packet chain. 
48
49         \warning It is not permissible to change data belonging to a following
50             packet/header/interpreter even though this data is part of \c this sequence. Doing so
51             will corrupt the packet data.
52         
53         \par
54
55         \warning When accessing packet data via the PacketData interface you are on your own: The
56             packet is not validated in any way, you bypass all parsers.
57
58         All public members are those of an STL random-access sequence.
59
60         \implementation This class is very tightly integrated with PacketInterpreterBase /
61             PacketInterpreter. It is separated out of those classes primarily to provide a clean
62             sequence interface to the library user and not for implementation reasons (it would have
63             been simpler to implement all these members in PacketInterpreterBase).
64
65         \ingroup packet_module
66       */
67     class PacketData
68         : boost::noncopyable
69     {
70     public:
71         ///////////////////////////////////////////////////////////////////////////
72         // Types
73
74         typedef senf::detail::packet::iterator iterator;
75         typedef senf::detail::packet::const_iterator const_iterator;
76         typedef senf::detail::packet::size_type size_type;
77         typedef senf::detail::packet::difference_type difference_type;
78         typedef senf::detail::packet::byte byte;
79         typedef byte value_type;
80         typedef byte & reference;
81         typedef byte const & const_reference;
82         typedef byte * pointer;
83         typedef byte const * const_pointer;
84
85         ///////////////////////////////////////////////////////////////////////////
86         ///\name Structors and default members
87         ///@{
88
89         // no public constructors
90         // no conversion constructors
91
92         ///@}
93         ///////////////////////////////////////////////////////////////////////////
94     
95         ///\name Sequence interface to raw data
96         ///@{
97
98         iterator begin() const;
99         iterator end() const;
100         size_type size() const;
101         bool empty() const;
102         byte operator[](size_type n) const;
103         byte & operator[](size_type n);
104
105         // Modifying the raw packet data
106
107         // IMPORTANT NOTE: It is not possible to insert data AFTER an empty packet
108         // since for an empty packet begin() == end(). However, I hope this problem is
109         // only academic since what should an empty packet be good for ?
110         void insert(iterator pos, byte v);
111         void insert(iterator pos, size_type n, byte v);
112         template <class InputIterator>
113         void insert(iterator pos, InputIterator f, InputIterator l,
114                     typename boost::disable_if< boost::is_convertible<InputIterator,size_type> >::type * = 0);
115
116         void erase(iterator pos);
117         void erase(iterator first, iterator last);
118         void clear();
119         
120         void resize(size_type n, byte v=0);
121
122         ///@}
123
124     protected:
125         PacketData(size_type b, size_type e);
126
127         /// Need to make this protected so we can change it in the derived class
128         detail::PacketImpl * impl_;
129
130         detail::PacketImpl & impl() const;
131
132         bool valid();
133
134     private:
135         size_type begin_;
136         size_type end_;
137
138         friend class detail::PacketImpl;
139     };
140
141     class PacketParserBase;
142
143     struct TruncatedPacketException : public std::exception
144     { virtual char const * what() const throw() { return "truncated packet"; } };
145
146     class safe_data_iterator
147         : public boost::iterator_facade< safe_data_iterator,
148                                          PacketData::value_type,
149                                          boost::random_access_traversal_tag >,
150           public ComparableSafeBool<safe_data_iterator>
151     {
152     public:
153         typedef PacketData::size_type size_type;
154
155         safe_data_iterator();
156         explicit safe_data_iterator(PacketData & data);
157         safe_data_iterator(PacketData & data, PacketData::iterator i);
158         explicit safe_data_iterator(PacketParserBase const & parser);
159
160         safe_data_iterator & operator=(PacketData::iterator i);
161         safe_data_iterator & operator=(PacketParserBase const & parser);
162         operator PacketData::iterator() const;
163
164         bool boolean_test() const;
165
166         PacketData & data() const;
167
168     private:
169         friend class boost::iterator_core_access;
170
171         // iterator_facade interface
172
173         value_type & dereference() const;
174         bool equal(safe_data_iterator const & other) const;
175         difference_type distance_to(safe_data_iterator const & other) const;
176         void increment();
177         void decrement();
178         void advance(difference_type n);
179
180         PacketData::iterator i() const;
181
182         PacketData * data_;
183         size_type i_;
184     };
185 }
186
187 ///////////////////////////////hh.e////////////////////////////////////////
188 #endif
189 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketData_i_)
190 #define HH_PacketData_i_
191 #include "PacketData.cci"
192 //#include "PacketData.ct"
193 #include "PacketData.cti"
194 #endif
195
196 \f
197 // Local Variables:
198 // mode: c++
199 // fill-column: 100
200 // c-file-style: "senf"
201 // indent-tabs-mode: nil
202 // ispell-local-dictionary: "american"
203 // compile-command: "scons -u test"
204 // comment-column: 40
205 // End:
206
207 //  LocalWords:  Fraunhofer Institut fuer offene Kommunikationssysteme FOKUS de
208 //  LocalWords:  Kompetenzzentrum Satelitenkommunikation SatCom Bund berlios dil
209 //  LocalWords:  PacketData hh STL PacketInterpreterBase PacketInterpreter
210 //  LocalWords:  ingroup Structors