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;
};
class BasePacket {
std::vector<int> fieldSizes;
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) {
this->fieldSizes.push_back(std::get<2>(tup));
});
}
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);
});
}
void initMemoryStructure(int numberOfField) {
this->structure.resize(numberOfField);
std::fill(this->structure.begin(), this->structure.end(), 0);
}
void updateStructureFromBinary() {
size_t num_bit_read = 0; // offset from the beginning of the byte
for (long unsigned int i = 0; i < this->fieldSizes.size(); i++) {
int bit_rem = this->fieldSizes[i]; //remaining bits to read
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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);
val += 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);
}
this->structure[i] = val;
}
}
public:
BasePacket(std::vector<std::tuple<int, std::string, int>> paramsTuple) {
this->updateFieldSizes(paramsTuple);
this->updateFieldNameAndIndexMap(paramsTuple);
this->initMemoryStructure(paramsTuple.size());
this->binaryPointer = new uint8_t[paramsTuple.size() * sizeof(size_t)]; //tot number of field times the maximum bytesize of the value;
}
virtual ~BasePacket() = default;
std::vector<int> const* getFieldSizes() const {
return &fieldSizes;
}
uint8_t const* getBinaryPointer() const {
return binaryPointer;
}
return &structure;
}
void copyToBinaryPointer(const uint8_t *from, uint size) {
std::memcpy(binaryPointer, from, size);
updateStructureFromBinary();
}
void copyToBinaryPointer(const uint8_t *from, uint size, uint offset) {
std::memcpy(&binaryPointer[offset], from, size);
updateStructureFromBinary();
}
size_t indexOfField(std::string fieldName) {
return this->fieldNameToIndexMap.at(fieldName);
}
std::string fieldNameOfIndex(size_t index) {
return this->indexToFieldNameMap.at(index);
}
int index = this->fieldNameToIndexMap.at(fieldName);
return this->structure[index];
}
std::vector<size_t>::const_iterator begin() const {
return this->structure.cbegin();
std::vector<size_t>::const_iterator end() const {
return this->structure.cend();
return this->structure.at(index);
}
virtual size_t getHeaderSize()=0;
virtual size_t getPayloadSize()=0;
virtual size_t getTailSize()=0;
virtual size_t getMaxPacketSize()=0;
};
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
template<template<typename > class T, typename V>
class BasePacketTempl : public BasePacket{
protected:
T<V> structure;
public:
BasePacketTempl(std::vector<std::tuple<int, std::string, int>> paramsTuple) : BasePacket(paramsTuple) {}
virtual ~BasePacketTempl() = default;
T<V> const* getStructure() const {
return &structure;
}
V operator[](int index) const {
return this->structure[index];
}
V operator[](std::string fieldName) const {
int index = this->fieldNameToIndexMap.at(fieldName);
return this->structure[index];
}
typename T<V>::const_iterator begin() const {
return this->getStructure()->cbegin();
}
typename T<V>::const_iterator end() const {
return this->getStructure()->cend();
}
V at(int index) const {
return this->structure.at(index);
}
};