storage_marshaller.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_STORAGE_MARSHALLER_HPP_INCLUDED
6 #define UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_STORAGE_MARSHALLER_HPP_INCLUDED
7 
9 #include <uavcan/debug.hpp>
12 #include <cstdlib>
13 
14 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
15 # include <cerrno>
16 #endif
17 
18 namespace uavcan
19 {
20 namespace dynamic_node_id_server
21 {
26 {
28 
30  {
31  const uint8_t ret = (ch > '9') ? static_cast<uint8_t>(ch - 'a' + 10) : static_cast<uint8_t>(ch - '0');
32  UAVCAN_ASSERT(ret < 16);
33  return ret;
34  }
35 
36 public:
38  : storage_(storage)
39  { }
40 
45  {
46  IStorageBackend::String serialized;
47  for (uint8_t i = 0; i < UniqueID::MaxSize; i++)
48  {
49  serialized.appendFormatted("%02x", key.at(i));
50  }
51  UAVCAN_ASSERT(serialized.size() == UniqueID::MaxSize * 2);
52  return serialized;
53  }
54 
62  int setAndGetBack(const IStorageBackend::String& key, uint32_t& inout_value)
63  {
64  IStorageBackend::String serialized;
65  serialized.appendFormatted("%llu", static_cast<unsigned long long>(inout_value));
66 
67  UAVCAN_TRACE("StorageMarshaller", "Set %s = %s", key.c_str(), serialized.c_str());
68  storage_.set(key, serialized);
69 
70  return get(key, inout_value);
71  }
72 
73  int setAndGetBack(const IStorageBackend::String& key, UniqueID& inout_value)
74  {
75  const IStorageBackend::String serialized = convertUniqueIDToHex(inout_value);
76 
77  UAVCAN_TRACE("StorageMarshaller", "Set %s = %s", key.c_str(), serialized.c_str());
78  storage_.set(key, serialized);
79 
80  return get(key, inout_value);
81  }
82 
90  int get(const IStorageBackend::String& key, uint32_t& out_value) const
91  {
92  /*
93  * Reading the storage
94  */
95  const IStorageBackend::String val = storage_.get(key);
96  if (val.empty())
97  {
98  return -ErrFailure;
99  }
100 
101  /*
102  * Per MISRA C++ recommendations, checking the inputs instead of relying solely on errno.
103  * The value must contain only numeric characters.
104  */
105  for (IStorageBackend::String::const_iterator it = val.begin(); it != val.end(); ++it)
106  {
107  if (static_cast<char>(*it) < '0' || static_cast<char>(*it) > '9')
108  {
109  return -ErrFailure;
110  }
111  }
112 
113  if (val.size() > 10) // len(str(0xFFFFFFFF))
114  {
115  return -ErrFailure;
116  }
117 
118  /*
119  * Conversion is carried out here
120  */
121 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
122  errno = 0;
123 #endif
124 
125 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
126  const unsigned long long x = std::strtoull(val.c_str(), UAVCAN_NULLPTR, 10);
127 #else
128  // There was no strtoull() before C++11, so we need to resort to strtoul()
129  StaticAssert<(sizeof(unsigned long) >= sizeof(uint32_t))>::check();
130  const unsigned long x = std::strtoul(val.c_str(), UAVCAN_NULLPTR, 10);
131 #endif
132 
133 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
134  if (errno != 0)
135  {
136  return -ErrFailure;
137  }
138 #endif
139 
140  out_value = static_cast<uint32_t>(x);
141  return 0;
142  }
143 
144  int get(const IStorageBackend::String& key, UniqueID& out_value) const
145  {
146  static const uint8_t NumBytes = UniqueID::MaxSize;
147 
148  /*
149  * Reading the storage
150  */
152  if (val.size() != NumBytes * 2)
153  {
154  return -ErrFailure;
155  }
156 
157  /*
158  * The value must contain only hexadecimal numbers.
159  */
161  for (IStorageBackend::String::const_iterator it = val.begin(); it != val.end(); ++it)
162  {
163  if ((static_cast<char>(*it) < '0' || static_cast<char>(*it) > '9') &&
164  (static_cast<char>(*it) < 'a' || static_cast<char>(*it) > 'f'))
165  {
166  return -ErrFailure;
167  }
168  }
169 
170  /*
171  * Conversion is carried out here
172  */
174 
175  for (uint8_t byte_index = 0; byte_index < NumBytes; byte_index++)
176  {
177  out_value[byte_index] =
178  static_cast<uint8_t>(convertLowerCaseHexCharToNibble(static_cast<char>(*it++)) << 4);
179  out_value[byte_index] =
180  static_cast<uint8_t>(convertLowerCaseHexCharToNibble(static_cast<char>(*it++)) | out_value[byte_index]);
181  }
182 
183  return 0;
184  }
185 };
186 
187 }
188 }
189 
190 #endif // Include guard
check
ROSCPP_DECL bool check()
UAVCAN_NULLPTR
#define UAVCAN_NULLPTR
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:51
uavcan::Array::size
EnableIf< sizeof((reinterpret_cast< const R * >0)) -> size()) &&sizeof((*(reinterpret_cast< const R * >(0)))[0])
types.hpp
debug.hpp
uavcan::ArrayImpl::end
ValueType * end()
Definition: array.hpp:351
uavcan::uint32_t
std::uint32_t uint32_t
Definition: std.hpp:26
uavcan::Array::empty
bool empty() const
Definition: array.hpp:712
uavcan::dynamic_node_id_server::StorageMarshaller
Definition: storage_marshaller.hpp:25
uavcan::dynamic_node_id_server::StorageMarshaller::convertLowerCaseHexCharToNibble
static uint8_t convertLowerCaseHexCharToNibble(char ch)
Definition: storage_marshaller.hpp:29
uavcan::dynamic_node_id_server::StorageMarshaller::setAndGetBack
int setAndGetBack(const IStorageBackend::String &key, uint32_t &inout_value)
Definition: storage_marshaller.hpp:62
uavcan::dynamic_node_id_server::StorageMarshaller::get
int get(const IStorageBackend::String &key, uint32_t &out_value) const
Definition: storage_marshaller.hpp:90
UAVCAN_TRACE
#define UAVCAN_TRACE(...)
Definition: libuavcan/libuavcan/include/uavcan/debug.hpp:31
uavcan::StaticAssert
struct UAVCAN_EXPORT StaticAssert
Definition: templates.hpp:29
uavcan::Array::appendFormatted
void appendFormatted(const char *const format, const A value)
Definition: array.hpp:888
storage_backend.hpp
uavcan::Array
Definition: array.hpp:424
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
uavcan::dynamic_node_id_server::StorageMarshaller::convertUniqueIDToHex
static IStorageBackend::String convertUniqueIDToHex(const UniqueID &key)
Definition: storage_marshaller.hpp:44
uavcan::dynamic_node_id_server::IStorageBackend
Definition: storage_backend.hpp:22
uavcan::ArrayImpl< T, ArrayMode, MaxSize_ >::const_iterator
const typedef ValueType * const_iterator
Definition: array.hpp:371
uavcan::dynamic_node_id_server::StorageMarshaller::StorageMarshaller
StorageMarshaller(IStorageBackend &storage)
Definition: storage_marshaller.hpp:37
uavcan::Array::begin
EnableIf< sizeof((reinterpret_cast< const R * >0)) -> begin()) &&sizeof((reinterpret_cast< const R * >(0)) -> size())>::Type packSquareMatrix(const R &src_row_major)
Definition: array.hpp:1006
build_config.hpp
uavcan::dynamic_node_id_server::StorageMarshaller::get
int get(const IStorageBackend::String &key, UniqueID &out_value) const
Definition: storage_marshaller.hpp:144
uavcan::dynamic_node_id_server::StorageMarshaller::storage_
IStorageBackend & storage_
Definition: storage_marshaller.hpp:27
uavcan::dynamic_node_id_server::StorageMarshaller::setAndGetBack
int setAndGetBack(const IStorageBackend::String &key, UniqueID &inout_value)
Definition: storage_marshaller.hpp:73
uavcan::Array::convertToLowerCaseASCII
void convertToLowerCaseASCII()
Definition: array.hpp:940
uavcan::dynamic_node_id_server::IStorageBackend::set
virtual void set(const String &key, const String &value)=0
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
uavcan::dynamic_node_id_server::IStorageBackend::get
virtual String get(const String &key) const =0
uavcan::ArrayImpl::c_str
const char * c_str() const
Definition: array.hpp:321
uavcan::dynamic_node_id_server::UniqueID
protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id UniqueID
Definition: protocol/dynamic_node_id_server/types.hpp:22
libuavcan_dsdl_compiler.pyratemp.long
long
Definition: pyratemp.py:199
pyuavcan_v0.driver.timestamp_estimator.x
x
Definition: timestamp_estimator.py:221
UAVCAN_ASSERT
#define UAVCAN_ASSERT(x)
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:184


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:03