Newer
Older
/*
* PacketLib.h
*
* Created on: Nov 24, 2022
* Author: valerio
*/
#ifndef INCLUDE_BASEPACKET_H_
#define INCLUDE_BASEPACKET_H_
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
namespace inaf::oasbo::PacketLib {
class BasePacketStructure {
public:
virtual ~BasePacketStructure() = default;
virtual std::vector<std::tuple<int, std::string, int>> getPacketStructure() = 0;
};
std::map<std::string, int> fieldNameToIndexMap;
std::map<int, std::string> indexToFieldNameMap;
uint8_t *binaryPointer;
void updateFieldSizes(
const std::vector<std::tuple<int, std::string, int>> ¶msTuple) {
std::for_each(paramsTuple.begin(), paramsTuple.end(),
[&](const std::tuple<int, std::string, int> &tup) {
void updateFieldOffsets(
const std::vector<std::tuple<int, std::string, int>> ¶msTuple) {
size_t offset = 0;
for (size_t i = 0; i < paramsTuple.size(); i++) {
fieldNameToOffsetsMap[i] = offset;
offset += std::get < 2 > (paramsTuple[i]);
}
}
void updateFieldNameAndIndexMap(
const std::vector<std::tuple<int, std::string, int>> ¶msTuple) {
std::for_each(paramsTuple.begin(), paramsTuple.end(),
[&](const std::tuple<int, std::string, int> &tup) {
this->fieldNameToIndexMap[std::get < 1 > (tup)] = std::get
< 0 > (tup);
this->indexToFieldNameMap[std::get < 0 > (tup)] = std::get
< 1 > (tup);
});
}
public:
BasePacket(std::vector<std::tuple<int, std::string, int>> paramsTuple) {
this->updateFieldSizes(paramsTuple);
this->updateFieldNameAndIndexMap(paramsTuple);
this->binaryPointer = new uint8_t[paramsTuple.size() * sizeof(size_t)]; //tot number of field times the maximum bytesize of the value;
}
virtual ~BasePacket() = default;
size_t readValueFromBinaryAt(int index) {
size_t num_bit_read = fieldNameToOffsetsMap[index]; // offset from the beginning of the byte
int bit_rem = this->fieldSizes[index]; //remaining bits to read
size_t value = 0; //final value of the field
while (bit_rem > 0) {
size_t read = this->binaryPointer[num_bit_read / 8];
size_t mask = std::pow(2, 8 - num_bit_read % 8) - 1;
read = read & mask;
bit_rem = bit_rem - 8 + num_bit_read % 8;
read = (bit_rem >= 0) * (read << bit_rem)
+ (bit_rem < 0) * (read >> -bit_rem);
value += read;
num_bit_read = (bit_rem > 0) * (num_bit_read + 8 - num_bit_read % 8)
+ (bit_rem <= 0)
* (num_bit_read + 8 - num_bit_read % 8 + bit_rem);
}
return value;
}
std::vector<int> const* getFieldSizes() const {
return &fieldSizes;
}
uint8_t const* getBinaryPointer() const {
return binaryPointer;
}
void copyToBinaryPointer(const uint8_t *from, uint size) {
std::memcpy(binaryPointer, from, size);
}
void copyToBinaryPointer(const uint8_t *from, uint size, uint offset) {
std::memcpy(&binaryPointer[offset], from, size);
}
size_t indexOfField(std::string fieldName) {
return this->fieldNameToIndexMap.at(fieldName);
}
std::string fieldNameOfIndex(size_t index) {
return this->indexToFieldNameMap.at(index);
}
size_t operator[](int index) {
return readValueFromBinaryAt(index);
size_t operator[](std::string fieldName) {
int index = this->fieldNameToIndexMap.at(fieldName);
return readValueFromBinaryAt(index);