1 #ifndef BYTE_VECTOR_HPP 2 #define BYTE_VECTOR_HPP 27 template <
typename T1>
37 template <
typename T1,
typename T2>
39 std::vector<uint8_t>(arg1, arg2),
49 template <typename T, typename std::enable_if<std::is_integral<T>::value,
53 for(
size_t i(0); i <
sizeof(val); ++i) {
54 this->push_back(val >> (i * 8) & 0xFF);
68 typename std::enable_if<std::is_floating_point<T>::value,
72 reinterpret_cast<T&
>(b.front()) = val;
89 template <
typename encoding_T,
typename T1,
typename T2,
90 typename std::enable_if<std::is_arithmetic<T1>::value,
92 typename std::enable_if<std::is_arithmetic<T2>::value,
94 bool pack(
const T1 val,
const T2 scale,
const T2
offset = 0) {
95 const T1 tmp = (val +
offset) * scale;
96 if(tmp <= std::numeric_limits<encoding_T>::min())
97 return pack(std::numeric_limits<encoding_T>::min());
98 else if(tmp >= std::numeric_limits<encoding_T>::max())
99 return pack(std::numeric_limits<encoding_T>::max());
100 return pack(static_cast<encoding_T>(tmp));
110 bool pack(
const std::string& val,
111 size_t max_len = std::numeric_limits<size_t>::max()) {
115 if(++count == max_len)
break;
131 size_t max_len = std::numeric_limits<size_t>::max()) {
135 if(++count == max_len)
break;
146 template <
typename T,
147 typename std::enable_if<std::is_base_of<Packable, T>::value,
150 return val.pack_into(*
this);
166 template <
typename encoding_T,
typename T1,
typename T2,
167 typename std::enable_if<std::is_arithmetic<T1>::value,
168 T1>::type* =
nullptr,
169 typename std::enable_if<std::is_arithmetic<T2>::value,
170 T2>::type* =
nullptr>
172 if(!val.
set())
return false;
173 return pack<encoding_T>(val(), scale,
offset);
184 size_t max_len = std::numeric_limits<size_t>::max()) {
185 if(!val.
set())
return false;
186 return pack(val(), max_len);
197 size_t max_len = std::numeric_limits<size_t>::max()) {
198 if(!val.
set())
return false;
199 return pack(val(), max_len);
210 if(!val.
set())
return false;
222 template <typename T, typename std::enable_if<std::is_integral<T>::value,
227 for(
size_t i(0); i <
sizeof(val); ++i) {
228 val |= (*this)[
offset++] << (8 * i);
253 template <
typename T,
254 typename std::enable_if<std::is_floating_point<T>::value,
258 val =
reinterpret_cast<const T&
>((*this)[
offset]);
272 size_t count = std::numeric_limits<size_t>::max())
const {
273 if(count == std::numeric_limits<size_t>::max())
279 for(
size_t i = 0; i < count; ++i) {
296 size_t count = std::numeric_limits<size_t>::max())
const {
297 if(count == std::numeric_limits<size_t>::max())
299 if(!
consume(count))
return false;
319 template <
typename encoding_T,
typename T1,
typename T2,
320 typename std::enable_if<std::is_arithmetic<T1>::value,
321 T1>::type* =
nullptr,
322 typename std::enable_if<std::is_arithmetic<T2>::value,
323 T2>::type* =
nullptr>
328 val =
static_cast<T1
>(tmp) / scale;
338 template <
typename T,
339 typename std::enable_if<std::is_base_of<Packable, T>::value,
342 return obj.unpack_from(*
this);
367 size_t count = std::numeric_limits<size_t>::max())
const {
381 size_t count = std::numeric_limits<size_t>::max())
const {
398 template <
typename encoding_T,
typename T1,
typename T2 = float,
399 typename std::enable_if<std::is_arithmetic<T1>::value,
400 T1>::type* =
nullptr,
401 typename std::enable_if<std::is_arithmetic<T2>::value,
402 T2>::type* =
nullptr>
404 return val.
set() = unpack<encoding_T>(val(), scale,
offset);
419 return this->begin() +
offset;
427 return this->begin() +
offset;
460 virtual bool pack_into(
ByteVector& data)
const = 0;
461 virtual bool unpack_from(
const ByteVector& data) = 0;
471 for(
const auto& v : val) {
472 s << uint32_t(v) <<
" ";
474 s << std::dec << std::endl;
Definition of a pure virtual class used to indicate that a child class can pack itself into a ByteVec...
bool pack(const ByteVector &data, size_t max_len=std::numeric_limits< size_t >::max())
Packs another ByteVector into the ByteVector.
ByteVector(T1 arg1)
ByteVector constructor.
bool unpack(T &val) const
Extracts little endian integers from the ByteVector. Consumes a number of bytes matching sizeof(T)...
ByteVector()
ByteVector constructor.
bool pack(const std::string &val, size_t max_len=std::numeric_limits< size_t >::max())
Packs string data into the ByteVector.
bool unpack(T &obj) const
unpack Unpacks an an object which inherits from type Packable
bool unpack(Value< std::string > &val, size_t count=std::numeric_limits< size_t >::max()) const
Extracts data from the ByteVector and stores it in a Value<std::string>. Consumes all remaining data ...
bool pack(const Value< T > &val)
Packs the contents of a Value<T> into the ByteVector.
bool unpack(std::string &val, size_t count=std::numeric_limits< size_t >::max()) const
Extracts data from the ByteVector and stores it in a std::string. Consumes all remaining data unless ...
bool unpack(ByteVector &val, size_t count=std::numeric_limits< size_t >::max()) const
Extracts data from the ByteVector and stores it in a another ByteVector. Consumes all remaining data ...
bool pack(const Value< std::string > &val, size_t max_len=std::numeric_limits< size_t >::max())
Packs a Value<std::string> into the ByteVector.
ByteVector(T1 arg1, T2 arg2)
ByteVector constructor.
bool unpack(Value< T > &val) const
Unpacks Value types other than string and ByteVector specializations.
std::vector< uint8_t >::const_iterator unpacking_iterator() const
Gives an iterator to the next element ready for unpacking.
bool pack(const T &val)
Packs integer types into the ByteVector. Ensures little endian packing.
bool unpack(Value< T1 > &val, T2 scale=1, T2 offset=0) const
Unpacks scaled Value types (e.g. scaled int to floating point) as val = (packed_val/scale)-offset.
bool pack(const T1 val, const T2 scale, const T2 offset=0)
Packs scaled values (e.g. float to scaled int) as packed_val = (val+offset)*scale.
bool consume(std::size_t count) const
Manually consumes data, thus skipping the values.
std::unique_ptr< ByteVector > ByteVectorUptr
asio::buffers_iterator< asio::streambuf::const_buffers_type > iterator
bool pack(const Value< T1 > val, const T2 scale, const T2 offset=0)
Packs scaled value types (e.g. value<float> to scaled int) as packed_val = (val+offset)*scale.
bool unpack(bool &val) const
unpack Extracts a boolen from a single byte
std::ostream & operator<<(std::ostream &s, const msp::ByteVector &val)
bool unpack(Value< ByteVector > &val, size_t count=std::numeric_limits< size_t >::max()) const
Extracts data from the ByteVector and stores it in a Value<ByteVector>. Consumes all remaining data u...
bool unpack(T1 &val, T2 scale, T2 offset=0) const
Unpacks scaled value types (e.g. scaled int to floating point) as val = (packed_val/scale)-offset.
bool set() const
Queries if the data has been set.
std::vector< uint8_t >::iterator unpacking_iterator()
Gives an iterator to the next element ready for unpacking.
bool pack(const Value< ByteVector > &val, size_t max_len=std::numeric_limits< size_t >::max())
Packs a Value<ByteVector> into the ByteVector.
std::size_t unpacking_remaining() const
Returns the number of bytes still avialable for unpacking.
std::size_t unpacking_offset() const
Gives the number of bytes which have already been consumed by unpack operations.
std::shared_ptr< ByteVector > ByteVectorPtr