libtins  4.0
pdu_iterator.h
1 /*
2  * Copyright (c) 2017, Matias Fontanini
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #ifndef TINS_PDU_ITERATOR_H
31 #define TINS_PDU_ITERATOR_H
32 
33 #include <iterator>
34 
35 namespace Tins {
36 
37 class PDU;
38 class Packet;
39 
43 template <typename Concrete>
45 public:
49  typedef std::bidirectional_iterator_tag iterator_category;
50 
54  typedef std::ptrdiff_t difference_type;
55 
59  Concrete& operator++() {
60  advance();
61  return static_cast<Concrete&>(*this);
62  }
63 
67  Concrete operator++(int) {
68  Concrete output = static_cast<Concrete&>(*this);
69  advance();
70  return output;
71  }
72 
76  Concrete& operator--() {
77  retreat();
78  return static_cast<Concrete&>(*this);
79  }
80 
84  Concrete operator--(int) {
85  Concrete output = static_cast<Concrete&>(*this);
86  retreat();
87  return output;
88  }
89 private:
90  void advance() {
91  Concrete& self = static_cast<Concrete&>(*this);
92  self = Concrete(self->inner_pdu());
93  }
94 
95  void retreat() {
96  Concrete& self = static_cast<Concrete&>(*this);
97  self = Concrete(self->parent_pdu());
98  }
99 };
100 
107 template <typename Concrete>
109  const PDU* lhs_pdu = static_cast<const Concrete&>(lhs).operator->();
110  const PDU* rhs_pdu = static_cast<const Concrete&>(rhs).operator->();
111  return lhs_pdu == rhs_pdu;
112 }
113 
120 template <typename Concrete>
122  return !(lhs == rhs);
123 }
124 
128 class PDUIterator : public PDUIteratorBase<PDUIterator> {
129 public:
133  typedef PDU* pointer;
134 
138  typedef PDU& reference;
139 
143  typedef PDU& value_type;
144 
150  PDUIterator(pointer pdu);
151 
155  pointer operator->();
156 
160  pointer operator->() const;
161 
165  PDU& operator*();
166 
170  const PDU& operator*() const;
171 private:
172  pointer pdu_;
173 };
174 
178 class ConstPDUIterator : public PDUIteratorBase<PDUIterator> {
179 public:
183  typedef const PDU* pointer;
184 
188  typedef const PDU& reference;
189 
193  typedef const PDU& value_type;
194 
200  ConstPDUIterator(pointer pdu);
201 
205  ConstPDUIterator(PDUIterator iterator);
206 
210  pointer operator->() const;
211 
215  value_type operator*() const;
216 private:
217  pointer pdu_;
218 };
219 
220 /*
221  * \brief PDU iterator class
222  *
223  * This class allows iterating all PDUs in a packet.
224  *
225  * Note that this keeps pointers to the original PDUs so you need to guarantee that they're
226  * still in scope while you iterate them.
227  */
228 template <typename Iterator>
230 public:
237  PDUIteratorRange(Iterator start, Iterator end)
238  : start_(start), end_(end) {
239 
240  }
241 
242  template <typename OtherIterator>
244  : start_(other.begin().operator->()), end_(other.end().operator->()) {
245 
246  }
247 
248  /*
249  * Gets the beginning of the range
250  */
251  Iterator begin() {
252  return start_;
253  }
254 
255  /*
256  * Gets the beginning of the range
257  */
258  Iterator begin() const {
259  return start_;
260  }
261 
262  /*
263  * Gets the end of the range
264  */
265  Iterator end() {
266  return end_;
267  }
268 
269  /*
270  * Gets the end of the range
271  */
272  Iterator end() const {
273  return end_;
274  }
275 private:
276  Iterator start_;
277  Iterator end_;
278 };
279 
284 
289 
294 
299 
304 
309 
310 } // Tins
311 
312 #endif // TINS_PDU_ITERATOR_H
bool operator==(const PDUIteratorBase< Concrete > &lhs, const PDUIteratorBase< Concrete > &rhs)
Definition: pdu_iterator.h:108
std::ptrdiff_t difference_type
Definition: pdu_iterator.h:54
Concrete operator++(int)
Definition: pdu_iterator.h:67
Definition: packet.h:130
const PDU & reference
Definition: pdu_iterator.h:188
PDU & value_type
Definition: pdu_iterator.h:143
const PDU & value_type
Definition: pdu_iterator.h:193
Concrete & operator--()
Definition: pdu_iterator.h:76
PDUIteratorRange< PDUIterator > iterate_pdus(PDU *pdu)
Definition: pdu_iterator.cpp:80
std::bidirectional_iterator_tag iterator_category
Definition: pdu_iterator.h:49
PDU & reference
Definition: pdu_iterator.h:138
Definition: pdu_iterator.h:229
Definition: pdu_iterator.h:44
PDUIteratorRange(Iterator start, Iterator end)
Definition: pdu_iterator.h:237
The Tins namespace.
Definition: address_range.h:38
bool operator!=(const PDUIteratorBase< Concrete > &lhs, const PDUIteratorBase< Concrete > &rhs)
Definition: pdu_iterator.h:121
const PDU * pointer
Definition: pdu_iterator.h:183
Base class for protocol data units.
Definition: pdu.h:107
Definition: pdu_iterator.h:178
Definition: pdu_iterator.h:128
Concrete & operator++()
Definition: pdu_iterator.h:59
Concrete operator--(int)
Definition: pdu_iterator.h:84
PDU * pointer
Definition: pdu_iterator.h:133