Move sourcecode into 'senf/' directory
[senf.git] / senf / Packets / PacketData.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 PacketData public header */
25
26 #ifndef HH_SENF_Packets_PacketData_
27 #define HH_SENF_Packets_PacketData_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31 #include <boost/type_traits.hpp>
32 #include "../Utils/safe_bool.hh"
33 #include "../Utils/Exception.hh"
34 #include "PacketTypes.hh"
35
36 //#include "PacketData.mpp"
37 ///////////////////////////////hh.p////////////////////////////////////////
38
39 namespace senf {
40
41     /** \brief Packet data STL-sequence view
42
43         The PacketData class provides an STL-sequence compatible view of the raw packet data. Each
44         packet/header/interpreter in the chain references the same storage area, presenting a
45         different (but nested/overlapping) section of the data.
46
47         Whenever the data is manipulated through PacketData, the change is assumed to be within the
48         data range of that packet: All insertions take place \e inside \c this packet and \e outside
49         any following packets in the packet chain. 
50
51         \warning It is not permissible to change data belonging to a following
52             packet/header/interpreter even though this data is part of \c this sequence. Doing so
53             will corrupt the packet data.
54         
55         \par
56
57         \warning When accessing packet data via the PacketData interface you are on your own: The
58             packet is not validated in any way, you bypass all parsers.
59
60         All public members are those of an STL random-access sequence.
61
62         \implementation This class is very tightly integrated with PacketInterpreterBase /
63             PacketInterpreter. It is separated out of those classes primarily to provide a clean
64             sequence interface to the library user and not for implementation reasons (it would have
65             been simpler to implement all these members in PacketInterpreterBase).
66
67         \ingroup packet_module
68       */
69     class PacketData
70         : boost::noncopyable
71     {
72     public:
73         ///////////////////////////////////////////////////////////////////////////
74         // Types
75
76         typedef senf::detail::packet::iterator iterator;
77         typedef senf::detail::packet::const_iterator const_iterator;
78         typedef senf::detail::packet::size_type size_type;
79         typedef senf::detail::packet::difference_type difference_type;
80         typedef senf::detail::packet::byte byte;
81         typedef byte value_type;
82         typedef byte & reference;
83         typedef byte const & const_reference;
84         typedef byte * pointer;
85         typedef byte const * const_pointer;
86
87         ///////////////////////////////////////////////////////////////////////////
88         ///\name Structors and default members
89         ///@{
90
91         // no public constructors
92         // no conversion constructors
93
94         ///@}
95         ///////////////////////////////////////////////////////////////////////////
96     
97         ///\name Sequence interface to raw data
98         ///@{
99
100         iterator begin() const; ///< Return iterator to beginning
101                                 /**< Returns an <em>random access iterator</em> referring to the
102                                      first byte of the packet data. */
103         iterator end() const; ///< Return iterator to end 
104                               /**< Returns an <em>random access iterator</em> referring to the 
105                                    byte past the end of the packet data. */
106         size_type size() const; ///< Returns the number of bytes in the packet data.
107         bool empty() const; ///< Test whether the packet data is empty.
108                             /**< Returns whether the packet data is empty, i.e. whether its size
109                                  is 0. This function does not modify the content of the packet 
110                                  data in any way. To clear the content use clear() */        
111         byte operator[](size_type n) const; ///< Access byte in the packet data
112         byte & operator[](size_type n); ///< Access byte in the packet data
113
114         // Modifying the raw packet data
115
116         // IMPORTANT NOTE: It is not possible to insert data AFTER an empty packet
117         // since for an empty packet begin() == end(). However, I hope this problem is
118         // only academic since what should an empty packet be good for ?
119         void insert(iterator pos, byte v);
120         void insert(iterator pos, size_type n, byte v);
121 #       ifndef DOXYGEN
122         template <class InputIterator>
123         void insert(iterator pos, InputIterator f, InputIterator l,
124                     typename boost::disable_if< boost::is_convertible<InputIterator,size_type> >::type * = 0);
125 #       else
126         template <class InputIterator>
127         void insert(iterator pos, InputIterator f, InputIterator l);
128 #       endif
129
130         void erase(iterator pos);
131         void erase(iterator first, iterator last);
132         void clear(); ///< All bytes of the packet data dropped, leaving the container with a size of 0. */
133         
134         void resize(size_type n, byte v=0);
135
136         void reserve(size_type n);
137         size_type capacity() const;
138
139         ///@}
140
141     protected:
142         PacketData(size_type b, size_type e);
143
144         /// Need to make this protected so we can change it in the derived class
145         detail::PacketImpl * impl_;
146
147         detail::PacketImpl & impl() const;
148
149         bool valid();
150
151     private:
152         size_type begin_;
153         size_type end_;
154
155         friend class detail::PacketImpl;
156     };
157
158     class PacketParserBase;
159
160     /** \brief Invalid packet data access
161
162         This exception is signaled whenever an operation tries to access an out-of-bounds data
163         byte. If the packet has been implemented correctly, this signals a malformed packet.
164      */
165     struct TruncatedPacketException : public senf::Exception
166     { TruncatedPacketException() : senf::Exception("truncated packet"){} };
167
168 }
169
170 ///////////////////////////////hh.e////////////////////////////////////////
171 #endif
172 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketData_i_)
173 #define HH_SENF_Packets_PacketData_i_
174 #include "PacketData.cci"
175 //#include "PacketData.ct"
176 #include "PacketData.cti"
177 #endif
178
179 \f
180 // Local Variables:
181 // mode: c++
182 // fill-column: 100
183 // c-file-style: "senf"
184 // indent-tabs-mode: nil
185 // ispell-local-dictionary: "american"
186 // compile-command: "scons -u test"
187 // comment-column: 40
188 // End:
189