/* * PacketLib.h * * Created on: Nov 24, 2022 * Author: valerio */ #ifndef INCLUDE_BASEPACKET_H_ #define INCLUDE_BASEPACKET_H_ #include #include #include #include #include #include #include namespace inaf::oasbo::PacketLib { class BasePacketStructure { public: virtual ~BasePacketStructure() = default; virtual std::vector> getPacketStructure() = 0; }; class _iterator; class BasePacket { protected: std::vector fieldSizes; std::map fieldNameToOffsetsMap; std::map fieldNameToIndexMap; std::map indexToFieldNameMap; uint8_t *binaryPointer; void updateFieldSizes( const std::vector> ¶msTuple) { std::for_each(paramsTuple.begin(), paramsTuple.end(), [&](const std::tuple &tup) { this->fieldSizes.push_back(std::get < 2 > (tup)); }); } void updateFieldOffsets( const std::vector> ¶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> ¶msTuple) { std::for_each(paramsTuple.begin(), paramsTuple.end(), [&](const std::tuple &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> paramsTuple) { this->updateFieldSizes(paramsTuple); this->updateFieldNameAndIndexMap(paramsTuple); this->updateFieldOffsets(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 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); } virtual size_t getHeaderSize()=0; virtual size_t getPayloadSize()=0; virtual size_t getTailSize()=0; virtual size_t getMaxPacketSize()=0; }; } #endif