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