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;
};
template<template<typename > class T, typename V>
class BasePacket {
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
std::vector<int> fieldSizes;
T<V> structure;
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
V val = 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);
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;
}
T<V> const* getStructure() const {
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);
}
V getNumberOfFields() {
return this->structure.size();
}
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>::iterator begin() const {
return this->getStructure()->begin();
}
typename T<V>::iterator end() const {
return this->getStructure()->end();
}
typename T<V>::const_iterator cbegin() const {
return this->getStructure()->cbegin();
}
typename T<V>::const_iterator cend() const {
return this->getStructure()->cend();
}
void setValueAt(int index, V val) const {
structure.at(index) = val;
}
V at(int index) const {
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;
};
}
#endif