CppSerdes  1.0
A serialization/deserialization library designed with embedded systems in mind
serdes_byte_iterator.h
Go to the documentation of this file.
1 #ifndef SERDES_BYTE_ITERATOR_H_
12 #define SERDES_BYTE_ITERATOR_H_
13 
14 #include "bitcpy_common.h"
15 
17 namespace serdes
18 {
22  {
23  public:
26  struct byte_segment
27  {
28  uint8_t *bytes = nullptr;
29  size_t num_bytes = 0u;
30  };
31 
35  class iterator
36  {
37  public:
38  inline explicit iterator(byte_iterator_type *parg) : p_parent(parg) {}
39  inline iterator &operator++()
40  {
41  if (p_parent != nullptr)
42  {
43  // for element_size == 1 or for big endian machines, the data is already in
44  // correctly ordered byte form, so it doesn't need to be iterated over
45  // and we can exit here immediately by setting p_parent == nullptr.
46  if (p_parent->buffer.element_size == 1 || !detail::on_little_endian_platform())
47  {
48  p_parent = nullptr;
49  }
50  // for all other data, it needs to be iterated over to correct for endianness
51  else if (++p_parent->start_index && p_parent->start_index >= p_parent->end_plus_one_index)
52  {
53  p_parent = nullptr;
54  }
55  }
56  return *this;
57  }
58  inline bool operator!=(const iterator &) const
59  {
60  return p_parent != nullptr;
61  }
62  byte_segment &operator*()
63  {
64  if (p_parent == nullptr || p_parent->start_index >= p_parent->end_plus_one_index)
65  {
66  current_segment.bytes = nullptr;
67  current_segment.num_bytes = 0u;
68  return current_segment;
69  }
70  auto &p = *p_parent;
71  uint8_t *data = reinterpret_cast<uint8_t *>(p.buffer.value);
72  if (detail::on_little_endian_platform())
73  {
74  const size_t elem_sz = p.buffer.element_size;
75  if (elem_sz == 1u)
76  {
77  current_segment.bytes = &data[p.start_index];
78  current_segment.num_bytes = p.end_plus_one_index - p.start_index;
79  }
80  else if (elem_sz == 2u || elem_sz == 4u || elem_sz == 8u)
81  {
82  // this equation is the same as:
83  // "start_index + elem_sz - (start_index % elem_sz)*2 - 1u;"
84  // when elem_sz is power of 2
85  // used to find the byte offset that corrects for endianness flips for various element sizes
86  const size_t byte_offset = p.start_index + elem_sz - ((p.start_index & (elem_sz - 1u)) << 1) - 1u;
87  current_segment.bytes = &data[byte_offset];
88  current_segment.num_bytes = 1u;
89  }
90  else
91  {
92  current_segment.bytes = nullptr;
93  current_segment.num_bytes = 0u;
94  }
95  }
96  else
97  {
98  current_segment.bytes = &data[p.start_index];
99  current_segment.num_bytes = p.end_plus_one_index - p.start_index;
100  }
101  return current_segment;
102  }
103 
104  private:
105  byte_iterator_type *p_parent;
106  byte_segment current_segment{};
107  };
108  inline iterator begin() { return iterator(this); }
109  inline iterator end() { return iterator(nullptr); }
110 
111  private:
112  friend struct packet;
113  sized_pointer<void> &buffer;
114  size_t start_index;
115  size_t end_plus_one_index;
116  inline byte_iterator_type(
117  sized_pointer<void> &data_arg,
118  size_t starting_byte,
119  size_t ending_byte)
120  : buffer{data_arg},
121  start_index{starting_byte},
122  end_plus_one_index{ending_byte}
123  {
124  }
125  };
126 
130  {
131  size_t value = 0u;
132  explicit starting_byte_index(size_t val) : value{val} {}
133  };
134 
138  {
139  size_t value = 0u;
140  explicit number_of_bytes(size_t val) : value{val} {}
141  };
142 } // namespace serdes
143 
144 #endif // SERDES_BYTE_ITERATOR_H_
serdes::byte_iterator_type
allows iteration through the bytes of a buffer, even when the buffer's underlying type is not a byte ...
Definition: serdes_byte_iterator.h:21
serdes::starting_byte_index
explict type for representing a starting byte index (since it's easy to mess up the iterator inputs o...
Definition: serdes_byte_iterator.h:129
serdes::byte_iterator_type::byte_segment
provides a segment of 1 multiple bytes for packets that abstract an actual byte array,...
Definition: serdes_byte_iterator.h:26
bitcpy_common.h
Defines common bitcpy details as well as a info::version number, and bit_length function.
serdes::number_of_bytes
explict type for representing the number of bytes to iterate over (since it's easy to mess up the ite...
Definition: serdes_byte_iterator.h:137
serdes::byte_iterator_type::iterator
iterator that scans through the bytes, either one at a time when dealing with endianness details,...
Definition: serdes_byte_iterator.h:35
serdes
CppSerdes library namespace.
Definition: bitcpy_common.h:68
serdes::sized_pointer< void >::element_size
const uint_fast8_t element_size
Number of bytes per element of the original array type, same as sizeof(T_original)
Definition: bitcpy_sized_pointer.h:57