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;
146 size_t bit_size =
sizeof(
result) * 8;
149 ninth_byte <<= (bit_size - offset_start);
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;
193 if (endianess == bit_little_endian) {
201 (
sizeof(
result) * 8) - offset_end);
219 (((
sizeof(
result) * 8) - bit_length - offset_start) /
sizeof(
result)) * 8;
235 if (bit_length % 8 != 0) {
243 (uint8_t*)&
result + (bit_length / 8);
245 (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) {
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;
455template <
typename T,
int is_
signed,
int is_
floating_po
int>
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)
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)
568 uint8_t* buffer,
size_t start_bit,
size_t bit_length, T* value,
Endianess endianess)
571 if (
sizeof(T) * 8 == bit_length) {
592 uint8_t* buffer,
size_t start_bit,
size_t bit_length, T value,
Endianess endianess)
595 if (
sizeof(T) * 8 == bit_length) {
613 : _buffer(static_cast<uint8_t*>(data)),
614 _buffer_bytes(data_size),
615 _buffer_bits(_buffer_bytes * 8)
643 template <
typename T>
652 const auto result_code = checkForInvalidArguments(start_bit, bit_length,
sizeof(T));
653 return !result_code ? result_code :
654 Converter::read(_buffer, start_bit, bit_length, value, endianess);
674 template <
typename T>
683 const auto result_code = checkForInvalidArguments(start_bit, bit_length,
sizeof(T));
684 return !result_code ? result_code :
685 Converter::write(_buffer, start_bit, bit_length, value, endianess);
692 size_t _buffer_bytes;
710 size_t size_variable)
717 if (start_bit >= _buffer_bits) {
718 RETURN_ERROR_DESCRIPTION(ERR_INVALID_ARG,
"the start point to read/write is invalid (start bit index exceeds the buffer)");
722 if ((bit_length < 1) || (_buffer_bits < start_bit + bit_length)) {
723 RETURN_ERROR_DESCRIPTION(ERR_INVALID_ARG,
"the length to read/write is zero or the end point to read/write is invalid (end bit index exceeds the buffer)");
727 if (size_variable * 8 < bit_length) {
728 RETURN_ERROR_DESCRIPTION(ERR_INVALID_ARG,
"the size of the variable to read into / write from is invalid (exceeds the passed size to read/write)");
731 return a_util::result::SUCCESS;
std::string formatBits(uint64_t value)
a_util::result::Result convertSignalEndianess(uint64_t *signal, Endianess endianess, size_t bit_length)
BitSerializer(void *data, size_t data_size)
Definition bitserializer.h:612
a_util::result::Result read(size_t start_bit, size_t bit_length, T *value, Endianess endianess=get_platform_endianess())
Definition bitserializer.h:644
a_util::result::Result write(size_t start_bit, size_t bit_length, T value, Endianess endianess=get_platform_endianess())
Definition bitserializer.h:675
BitSerializer()
Definition bitserializer.h:622
Definition bitserializer.h:74
static a_util::result::Result readSignal(uint8_t *buffer, size_t start_bit, size_t bit_length, T *value, Endianess endianess=get_platform_endianess())
Definition bitserializer.h:89
static a_util::result::Result cutLeadingBits(uint64_t *value, size_t bit_length)
Definition bitserializer.h:385
static a_util::result::Result writeSignal(uint8_t *buffer, size_t start_bit, size_t bit_length, T value, Endianess endianess=get_platform_endianess())
Definition bitserializer.h:290
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)
Definition bitserializer.h:415
static a_util::result::Result write(uint8_t *buffer, size_t start_bit, size_t bit_length, T value, Endianess endianess)
Definition bitserializer.h:492
static a_util::result::Result read(uint8_t *buffer, size_t start_bit, size_t bit_length, T *value, Endianess endianess)
Definition bitserializer.h:474
static a_util::result::Result read(uint8_t *buffer, size_t start_bit, size_t bit_length, T *value, Endianess endianess)
Definition bitserializer.h:515
static a_util::result::Result write(uint8_t *buffer, size_t start_bit, size_t bit_length, T value, Endianess endianess)
Definition bitserializer.h:542
static a_util::result::Result read(uint8_t *buffer, size_t start_bit, size_t bit_length, T *value, Endianess endianess)
Definition bitserializer.h:567
static a_util::result::Result write(uint8_t *buffer, size_t start_bit, size_t bit_length, T value, Endianess endianess)
Definition bitserializer.h:591
Template converter class to differentiate between float, signed and unsigned integer values.
Definition bitserializer.h:456
Definition result_type_decl.h:34
#define RETURN_ERROR_DESCRIPTION(_errcode,...)
Definition error_def.h:39
Serves as component for memory access and management.
Definition memory.h:20
Endianess
Enum describing the endianess.
Definition bitserializer.h:31
Endianess get_platform_endianess()
bool copy(void *dest, std::size_t dest_size, const void *source, std::size_t bytes_to_copy)
Serves as component for functionality handling error and return types.
Definition result.h:20
Serves as the root component, with common functionality documented in core functionality.
Definition base.h:24
#define _MAKE_RESULT(_no, _label)
Definition result_info_decl.h:36