network_utils.h
Go to the documentation of this file.
1 /*
2 * Unpublished Copyright (c) 2009-2017 AutonomouStuff, LLC, All Rights Reserved.
3 *
4 * This file is part of the network_interface ROS 1.0 driver which is released under the MIT license.
5 * See file LICENSE included with this software or go to https://opensource.org/licenses/MIT for full license details.
6 */
7 
8 #ifndef NETWORK_INTERFACE_NETWORK_UTILS_H
9 #define NETWORK_INTERFACE_NETWORK_UTILS_H
10 
12 
13 #include <cstdint>
14 #include <vector>
15 #include <deque>
16 #include <typeinfo>
17 #include <string>
18 #include <cstring>
19 #include <type_traits>
20 
21 namespace AS
22 {
23 namespace Network
24 {
25 
26 // little-endian
27 template<class T, class C>
28 T read_le(const C& bufArray,
29  const uint32_t& offset,
30  const float& factor,
31  const float& valueOffset)
32 {
33  uint64_t rcvData = 0;
34 
35  for (uint32_t i = sizeof(T); i > 0; i--)
36  {
37  rcvData <<= 8;
38  // Need to use -1 because array is 0-based
39  // and offset is not.
40  rcvData |= bufArray[(offset - 1) + i];
41  }
42 
43  T* retVal;
44 
45  // Reinterpret the uint64_t as the provided type
46  retVal = reinterpret_cast<T*>(&rcvData);
47  *retVal *= static_cast<T>(factor);
48  *retVal += static_cast<T>(valueOffset);
49 
50  return *retVal;
51 };
52 
53 template<class T, class C>
54 T read_le(const C& bufArray,
55  const uint32_t& offset)
56 {
57  // Call the other signature of this function
58  // with a factor of 1.0 and an offset of 0.
59  return read_le<T>(bufArray, offset, 1.0, 0);
60 };
61 
62 template<class T>
63 std::vector<uint8_t> write_le(T *source,
64  typename std::enable_if<std::is_integral<T>::value>::type* = 0)
65 {
66  std::vector<uint8_t> ret_val;
67 
68  T mask = 0xFF;
69  uint32_t shift = 0;
70 
71  // Shift is the bitshift value to apply.
72  // It starts at 0 and increments by 8 bits
73  // for each byte.
74  while (shift < (8 * sizeof(T)))
75  {
76  ret_val.push_back(static_cast<uint8_t>((*source & mask) >> shift));
77  shift += 8;
78  mask <<= 8;
79  }
80 
81  return ret_val;
82 };
83 
84 template<class T>
85 std::vector<uint8_t> write_le(T *source,
86  typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
87 {
88  // This function handles floating-point values
89  // by finding an unsigned int of the same size
90  // and casting the raw bits of the floating-point
91  // value to an unsigned int, then calling this
92  // function recursively with that value.
93  if (sizeof(T) == sizeof(uint16_t))
94  {
95  return write_le<uint16_t>(
96  static_cast<uint16_t*>(
97  static_cast<void*>(source)));
98  }
99  else if (sizeof(T) == sizeof(uint32_t))
100  {
101  return write_le<uint32_t>(
102  static_cast<uint32_t*>(
103  static_cast<void*>(source)));
104  }
105  else if (sizeof(T) == sizeof(uint64_t))
106  {
107  return write_le<uint64_t>(
108  static_cast<uint64_t*>(
109  static_cast<void*>(source)));
110  }
111 };
112 
113 // big-endian
114 template<class T, class C>
115 T read_be(const C& bufArray,
116  const uint32_t& offset,
117  const float& factor,
118  const float& valueOffset)
119 {
120  uint64_t rcvData = 0;
121 
122  for (uint32_t i = 0; i < sizeof(T); i++)
123  {
124  rcvData <<= 8;
125  // Since we're counting up from 0 to size(T)
126  // we don't need the -1 here.
127  rcvData |= bufArray[(offset) + i];
128  }
129 
130  T* retVal;
131 
132  // Reinterpret the uint64_t as the provided type
133  retVal = reinterpret_cast<T*>(&rcvData);
134  *retVal *= static_cast<T>(factor);
135  *retVal += static_cast<T>(valueOffset);
136 
137  return *retVal;
138 };
139 
140 template<class T, class C>
141 T read_be(const C& bufArray,
142  const uint32_t& offset)
143 {
144  // Call the other signature of this function
145  // with a factor of 1.0 and an offset of 0.
146  return read_be<T>(bufArray, offset, 1.0, 0);
147 }
148 
149 template<class T>
150 std::vector<uint8_t> write_be(T *source,
151  typename std::enable_if<std::is_integral<T>::value>::type* = 0)
152 {
153  std::vector<uint8_t> ret_val;
154 
155  T mask = 0xFF;
156 
157  int shift = 8 * (sizeof(T) - 1);
158  mask <<= shift;
159 
160  // Shift is the bitshift value to apply.
161  // It starts at 8 * number of bytes of T - 1
162  // and decrements by 8 bits for each byte.
163  while (mask > 0)
164  {
165  ret_val.push_back(static_cast<uint8_t>((*source & mask) >> shift));
166  shift -= 8;
167  mask >>= 8;
168  }
169 
170  return ret_val;
171 };
172 
173 template<class T>
174 std::vector<uint8_t> write_be(T *source,
175  typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
176 {
177  // This function handles floating-point values
178  // by finding an unsigned int of the same size
179  // and casting the raw bits of the floating-point
180  // value to an unsigned int, then calling this
181  // function recursively with that value.
182  if (sizeof(T) == sizeof(uint16_t))
183  {
184  return write_be(
185  static_cast<uint16_t*>(
186  static_cast<void*>(source)));
187  }
188  else if (sizeof(T) == sizeof(uint32_t))
189  {
190  return write_be(
191  static_cast<uint32_t*>(
192  static_cast<void*>(source)));
193  }
194  else if (sizeof(T) == sizeof(uint64_t))
195  {
196  return write_be(
197  static_cast<uint64_t*>(
198  static_cast<void*>(source)));
199  }
200 }
201 
202 template<typename C>
203 inline int32_t find_magic_word(const C& in, const size_t& magic_word)
204 {
205  bool packet_found = false;
206  uint32_t i = 0;
207  uint32_t chunk = 0;
208  auto buf_size = in.size();
209 
210  // Read 4 bytes at a time
211  while (!packet_found && buf_size >= 4)
212  {
213  chunk = read_be<uint32_t>(in, i);
214 
215  if (chunk == magic_word)
216  {
217  packet_found = true;
218  return i;
219  }
220 
221  i++;
222  buf_size--;
223  }
224 
225  // Just in case
226  return -1;
227 };
228 
229 template<class T, class C>
231  const C& in,
232  T *out1,
233  T *out2,
234  ByteOrder bo,
235  const uint16_t& offset)
236 {
237  if (bo == ByteOrder::LE)
238  {
239  *out1 = read_le<T>(in, offset);
240  *out2 = read_le<T>(in, offset + sizeof(T));
241  }
242  else if (bo == ByteOrder::BE)
243  {
244  *out1 = read_be<T>(in, offset);
245  *out2 = read_be<T>(in, offset + sizeof(T));
246  }
247 };
248 
249 } // namespace Network
250 } // namespace AS
251 
252 #endif // NETWORK_INTERFACE_NETWORK_UTILS_H
AS::Network::parse_tuple
void parse_tuple(const C &in, T *out1, T *out2, ByteOrder bo, const uint16_t &offset)
Definition: network_utils.h:230
AS::Network::ByteOrder::LE
@ LE
AS::Network::read_le
T read_le(const C &bufArray, const uint32_t &offset, const float &factor, const float &valueOffset)
Definition: network_utils.h:28
AS::Network::ByteOrder::BE
@ BE
AS::Network::ByteOrder
ByteOrder
Definition: common.h:30
AS::Network::read_be
T read_be(const C &bufArray, const uint32_t &offset, const float &factor, const float &valueOffset)
Definition: network_utils.h:115
AS
Definition: common.h:11
AS::Network::write_le
std::vector< uint8_t > write_le(T *source, typename std::enable_if< std::is_integral< T >::value >::type *=0)
Definition: network_utils.h:63
common.h
AS::Network::write_be
std::vector< uint8_t > write_be(T *source, typename std::enable_if< std::is_integral< T >::value >::type *=0)
Definition: network_utils.h:150
AS::Network::find_magic_word
int32_t find_magic_word(const C &in, const size_t &magic_word)
Definition: network_utils.h:203


network_interface
Author(s): Joshua Whitley , Daniel Stanek , Joe Kale
autogenerated on Wed Mar 2 2022 00:35:33