4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
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
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.
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.
19 // The Original Code is Fraunhofer FOKUS code.
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.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief SafeIterator public header */
31 #ifndef HH_SENF_Packets_SafeIterator_
32 #define HH_SENF_Packets_SafeIterator_ 1
34 #ifndef HH_SENF_Packets_Packets_
35 #error "Don't include 'SafeIterator.hh' directly, include 'Packets.hh'"
39 #include <boost/iterator/iterator_facade.hpp>
41 //#include "SafeIterator.mpp"
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
46 /** \brief Re-validating data iterator
48 This class is a wrapper around a PacketData::iterator instance. It will revalidate the
49 iterator on every access. This keeps the iterator valid even when the data container is
50 resized and thereby possibly relocated. The iterator will always point to the byte at the
51 same offset from the packets beginning. If data is inserted before this iterators position,
52 the data pointed to will of course change.
54 For this to work, the safe_data_iterator must be initialized with the container to which the
55 iterator belongs. After this initialization it can be used like any other iterator.
57 class safe_data_iterator
58 : public boost::iterator_facade< safe_data_iterator,
59 PacketData::value_type,
60 boost::random_access_traversal_tag >,
61 public comparable_safe_bool<safe_data_iterator>
64 typedef PacketData::size_type size_type;
66 safe_data_iterator(); ///< Make uninitialized iterator
67 explicit safe_data_iterator(PacketData & data);
68 ///< Construct iterator only setting the data container
69 safe_data_iterator(PacketData & data, PacketData::iterator i);
70 ///< Initialize iterator to given position
71 explicit safe_data_iterator(PacketParserBase const & parser);
72 ///< Initialize iterator from parser
73 /**< The iterator will point to the parsers start
76 safe_data_iterator & operator=(PacketData::iterator i); ///< Assign iterator
77 /**< The iterator \a i must be from the container which \c
78 this iterator has been initialized. */
79 safe_data_iterator & operator=(PacketParserBase const & parser);
80 ///< Assign iterator from parser
81 /**< The iterator will point to the parser start
84 operator PacketData::iterator() const; ///< Convert to iterator
86 bool boolean_test() const; ///< Check, if iterator is initialized
88 PacketData & data() const; ///< Access data container
91 friend class boost::iterator_core_access;
93 // iterator_facade interface
95 value_type & dereference() const;
96 bool equal(safe_data_iterator const & other) const;
97 difference_type distance_to(safe_data_iterator const & other) const;
100 void advance(difference_type n);
102 PacketData::iterator i() const;
108 /** \brief Iterator re-validating Parser wrapper
110 An ordinary parser will be invalidated whenever the raw data container's size is
111 changed. This can complicate some algorithms considerably.
113 This wrapper will update the parsers iterator (the value returned by the i() member) on
114 every access. This ensures that the iterator will stay valid.
116 \attention Beware however, if you insert or remove data before the safe wrapper, the
117 location will \e not be updated accordingly and therefore the parser will be
120 Additionally a SafePacketParserWrapper has an uninitialized state. The only allowed operations in
121 this state are the boolean test for validity and assigning another parser.
123 \ingroup packetparser
125 template <class Parser>
126 class SafePacketParserWrapper
127 : public safe_bool< SafePacketParserWrapper<Parser> >
130 //-////////////////////////////////////////////////////////////////////////
133 //-////////////////////////////////////////////////////////////////////////
134 ///\name Structors and default members
137 // default copy constructor
138 // default copy assignment
139 // default destructor
140 SafePacketParserWrapper(); ///< Create an empty uninitialized SafePacketParserWrapper
142 // conversion constructors
143 SafePacketParserWrapper(Parser parser); ///< Initialize SafePacketParserWrapper from \a parser
145 SafePacketParserWrapper & operator=(Parser parser); ///< Assign \a parser to \c this
148 //-////////////////////////////////////////////////////////////////////////
150 Parser & operator*() const; ///< Access the stored parser
151 /**< On every access, the stored parsers iterator will be
152 updated / re-validated. */
153 Parser * operator->() const; ///< Access the stored parser
154 /**< On every access, the stored parsers iterator will be
155 updated / re-validated. */
156 bool boolean_test() const; ///< Check validity
161 mutable boost::optional<Parser> parser_;
162 senf::safe_data_iterator i_;
167 //-/////////////////////////////////////////////////////////////////////////////////////////////////
169 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_SafeIterator_i_)
170 #define HH_SENF_Packets_SafeIterator_i_
171 #include "SafeIterator.cci"
172 //#include "SafeIterator.ct"
173 #include "SafeIterator.cti"
180 // comment-column: 40
181 // c-file-style: "senf"
182 // indent-tabs-mode: nil
183 // ispell-local-dictionary: "american"
184 // compile-command: "scons -u test"