Original project changes: Vehicle - Add buffer handling tools to ovms utils
This commit is contained in:
parent
58402124dd
commit
f6f72e8c16
|
@ -612,3 +612,19 @@ std::string idtag(const char* tag, void* instance)
|
||||||
std::string res = buf.str();
|
std::string res = buf.str();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_buff_string: Helper function to get at string value from sized buffer.
|
||||||
|
*/
|
||||||
|
bool get_buff_string(const uint8_t *data, uint32_t size, uint32_t index, uint32_t len, std::string &strret)
|
||||||
|
{
|
||||||
|
int remain = size - index;
|
||||||
|
if (remain < 0)
|
||||||
|
return false;
|
||||||
|
if (remain < len)
|
||||||
|
len = remain;
|
||||||
|
const char *begin = reinterpret_cast<const char *>(data + index) ;
|
||||||
|
const char *end = begin + len;
|
||||||
|
strret.assign<const char *>(begin, end);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <vector>
|
||||||
#include "ovms.h"
|
#include "ovms.h"
|
||||||
|
|
||||||
// Macro utils:
|
// Macro utils:
|
||||||
|
@ -339,17 +340,187 @@ std::string idtag(const char* tag, void* instance);
|
||||||
#define IDTAG idtag(TAG,this)
|
#define IDTAG idtag(TAG,this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sign_extend: Sign extend an unsigned to a signed integer of the same size.
|
* sign_extend: Sign extend an unsigned to a signed integer of the same or bigger size.
|
||||||
|
* Sign bit is not known at compile time.
|
||||||
*/
|
*/
|
||||||
template <typename UINT, typename INT>
|
template<typename UINT, typename INT>
|
||||||
INT sign_extend(UINT uvalue, uint8_t signbit)
|
INT sign_extend( UINT uvalue, uint8_t signbit)
|
||||||
{
|
{
|
||||||
typedef typename std::make_unsigned<INT>::type uint_t;
|
typedef typename std::make_unsigned<INT>::type uint_t;
|
||||||
uint_t newuvalue = uvalue;
|
uint_t newuvalue = uvalue;
|
||||||
if (newuvalue & (UINT(1U) << signbit)) {
|
UINT signmask = UINT(1U) << signbit;
|
||||||
newuvalue |= ~((uint_t(1U) << signbit) - 1);
|
if ( newuvalue & signmask)
|
||||||
|
newuvalue |= ~ (static_cast<uint_t>(signmask) - 1);
|
||||||
|
return reinterpret_cast<INT &>(uvalue);
|
||||||
}
|
}
|
||||||
return reinterpret_cast<INT &>(newuvalue);
|
|
||||||
|
/**
|
||||||
|
* sign_extend: Sign extend an unsigned to a signed integer of the same or bigger size.
|
||||||
|
* Sign bit is known at compile time.
|
||||||
|
*/
|
||||||
|
template<typename UINT, typename INT, uint8_t SIGNBIT>
|
||||||
|
INT sign_extend( UINT uvalue)
|
||||||
|
{
|
||||||
|
typedef typename std::make_unsigned<INT>::type uint_t;
|
||||||
|
uint_t newuvalue = uvalue;
|
||||||
|
if ( newuvalue & ( UINT(1U) << SIGNBIT) )
|
||||||
|
newuvalue |= ~((uint_t(1U) << SIGNBIT) - 1);
|
||||||
|
return reinterpret_cast<INT &>(uvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_bit: Get at a specific (compile-time defined) bit in a byte.
|
||||||
|
*/
|
||||||
|
template<uint8_t BIT>
|
||||||
|
bool get_bit(uint8_t data)
|
||||||
|
{
|
||||||
|
return (0 != (data & (1 << BIT)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper to provide a big endian integer from a given number of bytes.
|
||||||
|
// The helper function checks the length before using this.
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
struct ovms_bytes_impl_t
|
||||||
|
{
|
||||||
|
static uint32_t get_bytes_int(const uint8_t *data, uint32_t index)
|
||||||
|
{
|
||||||
|
return (data[index + (BYTES - 1)])
|
||||||
|
| (ovms_bytes_impl_t < BYTES - 1 >::get_bytes_int(data, index) << 8);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct ovms_bytes_impl_t<1>
|
||||||
|
{
|
||||||
|
static uint32_t get_bytes_int(const uint8_t *data, uint32_t index)
|
||||||
|
{
|
||||||
|
return (data[index]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper Class to access Little-Endian values.
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
struct get_bytes_le_impl_t
|
||||||
|
{
|
||||||
|
static uint32_t get_bytes_int( const uint8_t *data, uint32_t index)
|
||||||
|
{
|
||||||
|
return ((data[index + (BYTES - 1)]) << (8 * (BYTES - 1)))
|
||||||
|
| get_bytes_le_impl_t < BYTES - 1 >::get_bytes_int(data, index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct get_bytes_le_impl_t<1>
|
||||||
|
{
|
||||||
|
static uint32_t get_bytes_int(const uint8_t *data, uint32_t index)
|
||||||
|
{
|
||||||
|
return (data[index]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_uint_bytes_be: Access to unsigned integer (big-endian) in a data buffer.
|
||||||
|
*
|
||||||
|
* @return true If within bounds
|
||||||
|
*/
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
bool get_uint_bytes_be(const uint8_t *data, uint32_t index, uint32_t length, uint32_t &res)
|
||||||
|
{
|
||||||
|
if ((index + (BYTES - 1)) >= length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
res = ovms_bytes_impl_t<BYTES>::get_bytes_int(data, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_int_bytes_be: Access to signed integer (big-endian) in a data buffer.
|
||||||
|
* @return true If within bounds
|
||||||
|
*/
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
bool get_int_bytes_be(const uint8_t *data, uint32_t index, uint32_t length, int32_t &res)
|
||||||
|
{
|
||||||
|
if ((index + (BYTES - 1)) >= length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32_t uresult = ovms_bytes_impl_t<BYTES>::get_bytes_int(data, index);
|
||||||
|
res = reinterpret_cast<int32_t &>(uresult);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_uint_buff_be: Access to unsigned integer (big-endian) in a vector data buffer.
|
||||||
|
* @return true If successful
|
||||||
|
*/
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
bool get_uint_buff_be(const std::string &data, uint32_t index, uint32_t &ures)
|
||||||
|
{
|
||||||
|
if ((index + (BYTES - 1)) >= data.size())
|
||||||
|
return false;
|
||||||
|
ures = ovms_bytes_impl_t<BYTES>::get_bytes_int(reinterpret_cast<const uint8_t *>(data.data()), index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_buff_int_be: Access to signed integer (big-endian) in a std::string data buffer.
|
||||||
|
* @return true If successful
|
||||||
|
*/
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
bool get_buff_int_be(const std::string &data, uint32_t index, int32_t &res)
|
||||||
|
{
|
||||||
|
if ((index + (BYTES - 1)) >= data.size())
|
||||||
|
return false;
|
||||||
|
uint32_t ures = ovms_bytes_impl_t<BYTES>::get_bytes_int(reinterpret_cast<const uint8_t *>(data.data()), index);
|
||||||
|
|
||||||
|
res = sign_extend < uint32_t, int32_t, BYTES * 8 - 1 > (ures);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_bytes_uint_le: Access to unsigned integer (little-endian) in a data buffer.
|
||||||
|
* @return true If within bounds
|
||||||
|
*/
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
bool get_bytes_uint_le(const uint8_t *data, uint32_t index, uint32_t length, uint32_t &res)
|
||||||
|
{
|
||||||
|
if ((index + (BYTES - 1)) >= length)
|
||||||
|
return false;
|
||||||
|
res = get_bytes_le_impl_t<BYTES>::get_bytes_int(data, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Access to unsigned integer (little-endian) in a vector data buffer.
|
||||||
|
* @return true If within bounds
|
||||||
|
*/
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
bool get_buff_uint_le(const std::string &data, uint32_t index, uint32_t &res)
|
||||||
|
{
|
||||||
|
if ((index + (BYTES - 1)) >= data.size())
|
||||||
|
return false;
|
||||||
|
res = get_bytes_le_impl_t<BYTES>::get_bytes_int(reinterpret_cast<const uint8_t *>(data.data()), index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Access to signed integer (little-endian) in a vector data buffer.
|
||||||
|
* @return true If within bounds
|
||||||
|
*/
|
||||||
|
template<uint8_t BYTES>
|
||||||
|
bool get_buff_int_le(const std::string &data, uint32_t index, int32_t &res)
|
||||||
|
{
|
||||||
|
if ((index + (BYTES - 1)) >= data.size())
|
||||||
|
return false;
|
||||||
|
uint32_t uresult = ovms_bytes_impl_t<BYTES>::get_bytes_int(reinterpret_cast<const uint8_t *>(data.data()), index);
|
||||||
|
res = sign_extend < uint32_t, int32_t, BYTES * 8 - 1 > (uresult);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Access a string portion in a vector data buffer.
|
||||||
|
* @return true if start is within bounds.
|
||||||
|
*/
|
||||||
|
bool get_buff_string(const uint8_t *data, uint32_t size, uint32_t index, uint32_t len, std::string &strret);
|
||||||
|
|
||||||
|
inline bool get_buff_string(const std::string &data, uint32_t index, uint32_t len, std::string &strret)
|
||||||
|
{
|
||||||
|
return get_buff_string(reinterpret_cast<const uint8_t *>(data.data()), data.size(), index, len, strret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __OVMS_UTILS_H__
|
#endif // __OVMS_UTILS_H__
|
||||||
|
|
Loading…
Reference in a new issue