14 #ifndef A_UTILS_UTIL_MEMORY_BITSERIALIZER_INCLUDED
15 #define A_UTILS_UTIL_MEMORY_BITSERIALIZER_INCLUDED
32 bit_little_endian = 1,
108 uint64_t ninth_byte = 0;
109 size_t bytes_to_read = 0;
115 size_t offset_start = start_bit % 8;
118 size_t offset_end = (8 - ((start_bit + bit_length) % 8)) % 8;
138 result >>= offset_start;
146 size_t bit_size =
sizeof(result) * 8;
149 ninth_byte <<= (bit_size - offset_start);
151 result = result | ninth_byte;
155 if (endianess == bit_big_endian) {
157 if (bit_length % 8 != 0) {
163 result <<= (offset_end + offset_start) % 8;
171 uint8_t* ms_byte = (uint8_t*)&result;
172 ms_byte[0] >>= (offset_end + offset_start) % 8;
180 detail::convertSignalEndianess(&result, endianess, bit_length);
190 detail::convertSignalEndianess(&result, bit_little_endian,
sizeof(result) * 8);
193 if (endianess == bit_little_endian) {
201 (
sizeof(result) * 8) - offset_end);
208 result >>= offset_start;
219 (((
sizeof(result) * 8) - bit_length - offset_start) /
sizeof(result)) * 8;
232 result <<= offset_end;
235 if (bit_length % 8 != 0) {
243 (uint8_t*)&result + (bit_length / 8);
245 (offset_end + offset_start) % 8;
253 detail::convertSignalEndianess(&result,
265 cutLeadingBits(&result, bit_length + (offset_end + offset_start) % 8);
271 size_t sz = (std::min)(
sizeof(*value),
sizeof(result));
274 return a_util::result::SUCCESS;
297 uint64_t buffer_copy = 0;
298 uint64_t ninth_byte = 0;
299 size_t bytes_to_read = 0;
301 buffer, &buffer_copy, start_bit, bit_length, &ninth_byte, &bytes_to_read);
305 size_t offset_start = start_bit % 8;
307 size_t offset_end = (8 - ((start_bit + bit_length) % 8)) % 8;
308 uint64_t mask_left = ~0ULL;
309 if ((bit_length + offset_start) >= (
sizeof(mask_left) * 8)) {
314 mask_left <<= (bit_length + offset_start);
316 uint64_t mask = ~0ULL;
317 mask <<= offset_start;
331 int shift_amount = (int)offset_start;
334 if (endianess == bit_big_endian) {
336 detail::convertSignalEndianess(&signal, endianess, bit_length);
338 uint8_t* ms_byte = (uint8_t*)&signal;
339 int ms_shift = (8 - (bit_length % 8)) % 8;
340 ms_byte[0] <<= ms_shift;
341 shift_amount -= ms_shift;
345 if ((offset_start + bit_length) > (
sizeof(signal) * 8)) {
346 uint64_t signal_for_ninth_byte = signal;
347 signal_for_ninth_byte >>= (
sizeof(signal) - 1) * 8;
348 signal_for_ninth_byte >>= (8 - offset_start);
349 uint64_t mask_to_set = ~0ULL;
350 mask_to_set <<= (8 - offset_end);
351 ninth_byte &= mask_to_set;
352 ninth_byte |= signal_for_ninth_byte;
355 if (shift_amount < 0) {
356 signal >>= std::abs(shift_amount);
359 signal <<= shift_amount;
363 buffer_copy |= signal;
365 size_t sz = (std::min)(bytes_to_read,
sizeof(signal));
369 if (bytes_to_read >
sizeof(signal)) {
373 return a_util::result::SUCCESS;
387 size_t bit_size = (
sizeof(*value) * 8);
388 if (bit_length < bit_size) {
389 uint64_t mask = ~0ULL;
390 mask >>= (bit_size - bit_length);
394 return a_util::result::SUCCESS;
419 uint64_t* ninth_byte,
420 size_t* bytes_to_read)
423 size_t start_byte = start_bit / 8;
427 size_t bits_to_read = bit_length + (start_bit % 8);
428 if ((bits_to_read % 8) > 0) {
429 bits_to_read += (8 - (bits_to_read % 8));
432 *bytes_to_read = bits_to_read / 8;
435 if (*bytes_to_read > (
size_t)
sizeof(*value)) {
445 if (*bytes_to_read >
sizeof(*value)) {
450 return a_util::result::SUCCESS;
455 template <
typename T,
int is_
signed,
int is_
floating_po
int>
459 template <
typename T>
475 uint8_t* buffer,
size_t start_bit,
size_t bit_length, T* value,
Endianess endianess)
493 uint8_t* buffer,
size_t start_bit,
size_t bit_length, T value,
Endianess endianess)
500 template <
typename T>
516 uint8_t* buffer,
size_t start_bit,
size_t bit_length, T* value,
Endianess endianess)
520 if (res != a_util::result::SUCCESS) {
525 *value <<= (
sizeof(T) * 8) - bit_length;
526 *value >>= (
sizeof(T) * 8) - bit_length;
527 return a_util::result::SUCCESS;
543 uint8_t* buffer,
size_t start_bit,
size_t bit_length, T value,
Endianess endianess)
552 template <
typename T>
568 uint8_t* buffer,
size_t start_bit,
size_t bit_length, T* value,
Endianess endianess)
571 if (
sizeof(T) * 8 == bit_length) {
575 return ERR_INVALID_ARG;
592 uint8_t* buffer,
size_t start_bit,
size_t bit_length, T value,
Endianess endianess)
595 if (
sizeof(T) * 8 == bit_length) {
599 return ERR_INVALID_ARG;
613 :
_buffer(static_cast<uint8_t*>(data)),
643 template <
typename T>
653 return !result_code ? result_code :
654 Converter::read(
_buffer, start_bit, bit_length, value, endianess);
674 template <
typename T>
684 return !result_code ? result_code :
685 Converter::write(
_buffer, start_bit, bit_length, value, endianess);
710 size_t size_variable)
718 return ERR_INVALID_ARG;
722 if ((bit_length < 1) || (
_buffer_bits < start_bit + bit_length)) {
723 return ERR_INVALID_ARG;
727 if (size_variable * 8 < bit_length) {
728 return ERR_INVALID_ARG;
731 return a_util::result::SUCCESS;
uint8_t * _buffer
internal buffer
BitSerializer(void *data, size_t data_size)
Constructor.
size_t _buffer_bits
size of internal buffer in bits
a_util::result::Result write(size_t start_bit, size_t bit_length, T value, Endianess endianess=get_platform_endianess())
Write value to bitfield.
size_t _buffer_bytes
size of internal buffer in bytes
BitSerializer()
Default Constructor.
a_util::result::Result read(size_t start_bit, size_t bit_length, T *value, Endianess endianess=get_platform_endianess())
Read value from bitfield.
a_util::result::Result checkForInvalidArguments(size_t start_bit, size_t bit_length, size_t size_variable)
Check if the parameters for the reading and writing access are valid.
static a_util::result::Result write(uint8_t *buffer, size_t start_bit, size_t bit_length, T value, Endianess endianess)
Write unsigned integer to bitfield.
static a_util::result::Result read(uint8_t *buffer, size_t start_bit, size_t bit_length, T *value, Endianess endianess)
Read unsigned integer from bitfield.
static a_util::result::Result write(uint8_t *buffer, size_t start_bit, size_t bit_length, T value, Endianess endianess)
Write signed integer to bitfield.
static a_util::result::Result read(uint8_t *buffer, size_t start_bit, size_t bit_length, T *value, Endianess endianess)
Read signed integer from bitfield.
static a_util::result::Result write(uint8_t *buffer, size_t start_bit, size_t bit_length, T value, Endianess endianess)
Write tFloat to bitfield.
static a_util::result::Result read(uint8_t *buffer, size_t start_bit, size_t bit_length, T *value, Endianess endianess)
Read tFloat from bitfield.
Converter Base Contains the base methods used by all inheriting Converter classes.
static a_util::result::Result cutLeadingBits(uint64_t *value, size_t bit_length)
Set the highest bits of a uint64_t value to zero.
static a_util::result::Result writeSignal(uint8_t *buffer, size_t start_bit, size_t bit_length, T value, Endianess endianess=get_platform_endianess())
Write value to bitfield.
static a_util::result::Result copyBytesFromBuffer(uint8_t *buffer, uint64_t *value, size_t start_bit, size_t bit_length, uint64_t *ninth_byte, size_t *bytes_to_read)
Copy bytes_to_read number of bytes from the buffer to value and ninth_byte.
static a_util::result::Result readSignal(uint8_t *buffer, size_t start_bit, size_t bit_length, T *value, Endianess endianess=get_platform_endianess())
Read value from bitfield.
Template converter class to differentiate between float, signed and unsigned integer values.
A common result class usable as return value throughout.
Common include for component a_util::memory.
Endianess
Enum describing the endianess.
Endianess get_platform_endianess()
Returns the endianess of the platform.
bool copy(void *dest, std::size_t dest_size, const void *source, std::size_t bytes_to_copy)
Portable safe memcopy.
Serves as the root component, with common functionality documented in core functionality.
#define _MAKE_RESULT(_no, _label)
Create a result type and a constant instance of this type in an unnamed namespace.
Common include for component a_util::result.
std::string formatBits(uint64_t value)
Format the bit pattern of a uint64_t value to a string Used for debug purposes.
a_util::result::Result convertSignalEndianess(uint64_t *signal, Endianess endianess, size_t bit_length)
Convert the endianess of a signal by correctly swapping the byte order if required.