/* * 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 PacketLib { template class T> class BasePacket { private: std::vector fieldSizes; T structure; 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 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); }); } 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 size_t 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> 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; } std::vector const* getFieldSizes() const { return &fieldSizes; } uint8_t const* getBinaryPointer() const { return binaryPointer; } T 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); } size_t getNumberOfFields(){ return this->structure.size(); } size_t operator[](int index) const { return this->structure[index]; } size_t operator[](std::string fieldName) const { int index = this->fieldNameToIndexMap.at(fieldName); return this->structure[index]; } typename T::iterator begin() const { return this->getStructure()->begin(); } typename T::iterator end() const { return this->getStructure()->end(); } typename T::const_iterator cbegin() const { return this->getStructure()->cbegin(); } typename T::const_iterator cend() const { return this->getStructure()->cend(); } void setValueAt(int index, size_t val) const { structure.at(index) = val; } size_t at(int index) const { return this->structure.at(index); } }; } #endif /* INCLUDE_BASEPACKET_H_ */