Commit 25268f925224fb07d3e1ed097576493578421443
1 parent
ecb60b48
Add proper type for variable byte int
For the coming MQTT5 support, I'll need this a lot.
Showing
6 changed files
with
63 additions
and
46 deletions
CMakeLists.txt
| @@ -59,6 +59,7 @@ add_executable(FlashMQ | @@ -59,6 +59,7 @@ add_executable(FlashMQ | ||
| 59 | threadglobals.h | 59 | threadglobals.h |
| 60 | threadloop.h | 60 | threadloop.h |
| 61 | publishcopyfactory.h | 61 | publishcopyfactory.h |
| 62 | + variablebyteint.h | ||
| 62 | 63 | ||
| 63 | mainapp.cpp | 64 | mainapp.cpp |
| 64 | main.cpp | 65 | main.cpp |
| @@ -97,6 +98,7 @@ add_executable(FlashMQ | @@ -97,6 +98,7 @@ add_executable(FlashMQ | ||
| 97 | threadglobals.cpp | 98 | threadglobals.cpp |
| 98 | threadloop.cpp | 99 | threadloop.cpp |
| 99 | publishcopyfactory.cpp | 100 | publishcopyfactory.cpp |
| 101 | + variablebyteint.cpp | ||
| 100 | 102 | ||
| 101 | ) | 103 | ) |
| 102 | 104 |
FlashMQTests/FlashMQTests.pro
| @@ -50,6 +50,7 @@ SOURCES += tst_maintests.cpp \ | @@ -50,6 +50,7 @@ SOURCES += tst_maintests.cpp \ | ||
| 50 | ../threadglobals.cpp \ | 50 | ../threadglobals.cpp \ |
| 51 | ../threadloop.cpp \ | 51 | ../threadloop.cpp \ |
| 52 | ../publishcopyfactory.cpp \ | 52 | ../publishcopyfactory.cpp \ |
| 53 | + ../variablebyteint.cpp \ | ||
| 53 | mainappthread.cpp \ | 54 | mainappthread.cpp \ |
| 54 | twoclienttestcontext.cpp | 55 | twoclienttestcontext.cpp |
| 55 | 56 | ||
| @@ -92,6 +93,7 @@ HEADERS += \ | @@ -92,6 +93,7 @@ HEADERS += \ | ||
| 92 | ../threadglobals.h \ | 93 | ../threadglobals.h \ |
| 93 | ../threadloop.h \ | 94 | ../threadloop.h \ |
| 94 | ../publishcopyfactory.h \ | 95 | ../publishcopyfactory.h \ |
| 96 | + ../variablebyteint.h \ | ||
| 95 | mainappthread.h \ | 97 | mainappthread.h \ |
| 96 | twoclienttestcontext.h | 98 | twoclienttestcontext.h |
| 97 | 99 |
mqttpacket.cpp
| @@ -24,11 +24,6 @@ License along with FlashMQ. If not, see <https://www.gnu.org/licenses/>. | @@ -24,11 +24,6 @@ License along with FlashMQ. If not, see <https://www.gnu.org/licenses/>. | ||
| 24 | #include "utils.h" | 24 | #include "utils.h" |
| 25 | #include "threadglobals.h" | 25 | #include "threadglobals.h" |
| 26 | 26 | ||
| 27 | -RemainingLength::RemainingLength() | ||
| 28 | -{ | ||
| 29 | - memset(bytes, 0, 4); | ||
| 30 | -} | ||
| 31 | - | ||
| 32 | // constructor for parsing incoming packets | 27 | // constructor for parsing incoming packets |
| 33 | MqttPacket::MqttPacket(CirBuf &buf, size_t packet_len, size_t fixed_header_length, std::shared_ptr<Client> &sender) : | 28 | MqttPacket::MqttPacket(CirBuf &buf, size_t packet_len, size_t fixed_header_length, std::shared_ptr<Client> &sender) : |
| 34 | bites(packet_len), | 29 | bites(packet_len), |
| @@ -760,27 +755,7 @@ void MqttPacket::handlePubComp() | @@ -760,27 +755,7 @@ void MqttPacket::handlePubComp() | ||
| 760 | void MqttPacket::calculateRemainingLength() | 755 | void MqttPacket::calculateRemainingLength() |
| 761 | { | 756 | { |
| 762 | assert(fixed_header_length == 0); // because you're not supposed to call this on packet that we already know the length of. | 757 | assert(fixed_header_length == 0); // because you're not supposed to call this on packet that we already know the length of. |
| 763 | - | ||
| 764 | - size_t x = bites.size(); | ||
| 765 | - | ||
| 766 | - do | ||
| 767 | - { | ||
| 768 | - if (remainingLength.len > 4) | ||
| 769 | - throw std::runtime_error("Calculated remaining length is longer than 4 bytes."); | ||
| 770 | - | ||
| 771 | - char encodedByte = x % 128; | ||
| 772 | - x = x / 128; | ||
| 773 | - if (x > 0) | ||
| 774 | - encodedByte = encodedByte | 128; | ||
| 775 | - remainingLength.bytes[remainingLength.len++] = encodedByte; | ||
| 776 | - } | ||
| 777 | - while(x > 0); | ||
| 778 | -} | ||
| 779 | - | ||
| 780 | -RemainingLength MqttPacket::getRemainingLength() const | ||
| 781 | -{ | ||
| 782 | - assert(remainingLength.len > 0); | ||
| 783 | - return remainingLength; | 758 | + this->remainingLength = bites.size(); |
| 784 | } | 759 | } |
| 785 | 760 | ||
| 786 | void MqttPacket::setPacketId(uint16_t packet_id) | 761 | void MqttPacket::setPacketId(uint16_t packet_id) |
| @@ -846,7 +821,7 @@ size_t MqttPacket::getSizeIncludingNonPresentHeader() const | @@ -846,7 +821,7 @@ size_t MqttPacket::getSizeIncludingNonPresentHeader() const | ||
| 846 | if (fixed_header_length == 0) | 821 | if (fixed_header_length == 0) |
| 847 | { | 822 | { |
| 848 | total++; | 823 | total++; |
| 849 | - total += remainingLength.len; | 824 | + total += remainingLength.getLen(); |
| 850 | } | 825 | } |
| 851 | 826 | ||
| 852 | return total; | 827 | return total; |
| @@ -899,11 +874,6 @@ bool MqttPacket::containsFixedHeader() const | @@ -899,11 +874,6 @@ bool MqttPacket::containsFixedHeader() const | ||
| 899 | return fixed_header_length > 0; | 874 | return fixed_header_length > 0; |
| 900 | } | 875 | } |
| 901 | 876 | ||
| 902 | -char MqttPacket::getFirstByte() const | ||
| 903 | -{ | ||
| 904 | - return first_byte; | ||
| 905 | -} | ||
| 906 | - | ||
| 907 | char *MqttPacket::readBytes(size_t length) | 877 | char *MqttPacket::readBytes(size_t length) |
| 908 | { | 878 | { |
| 909 | if (pos + length > bites.size()) | 879 | if (pos + length > bites.size()) |
| @@ -991,11 +961,9 @@ void MqttPacket::readIntoBuf(CirBuf &buf) const | @@ -991,11 +961,9 @@ void MqttPacket::readIntoBuf(CirBuf &buf) const | ||
| 991 | 961 | ||
| 992 | if (!containsFixedHeader()) | 962 | if (!containsFixedHeader()) |
| 993 | { | 963 | { |
| 994 | - assert(remainingLength.len > 0); | ||
| 995 | - | ||
| 996 | - buf.headPtr()[0] = getFirstByte(); | 964 | + buf.headPtr()[0] = first_byte; |
| 997 | buf.advanceHead(1); | 965 | buf.advanceHead(1); |
| 998 | - buf.write(remainingLength.bytes, remainingLength.len); | 966 | + remainingLength.readIntoBuf(buf); |
| 999 | } | 967 | } |
| 1000 | else | 968 | else |
| 1001 | { | 969 | { |
mqttpacket.h
| @@ -33,13 +33,7 @@ License along with FlashMQ. If not, see <https://www.gnu.org/licenses/>. | @@ -33,13 +33,7 @@ License along with FlashMQ. If not, see <https://www.gnu.org/licenses/>. | ||
| 33 | #include "logger.h" | 33 | #include "logger.h" |
| 34 | #include "mainapp.h" | 34 | #include "mainapp.h" |
| 35 | 35 | ||
| 36 | -struct RemainingLength | ||
| 37 | -{ | ||
| 38 | - char bytes[4]; | ||
| 39 | - int len = 0; | ||
| 40 | -public: | ||
| 41 | - RemainingLength(); | ||
| 42 | -}; | 36 | +#include "variablebyteint.h" |
| 43 | 37 | ||
| 44 | class MqttPacket | 38 | class MqttPacket |
| 45 | { | 39 | { |
| @@ -51,7 +45,7 @@ class MqttPacket | @@ -51,7 +45,7 @@ class MqttPacket | ||
| 51 | std::vector<std::string> subtopics; | 45 | std::vector<std::string> subtopics; |
| 52 | std::vector<char> bites; | 46 | std::vector<char> bites; |
| 53 | size_t fixed_header_length = 0; // if 0, this packet does not contain the bytes of the fixed header. | 47 | size_t fixed_header_length = 0; // if 0, this packet does not contain the bytes of the fixed header. |
| 54 | - RemainingLength remainingLength; | 48 | + VariableByteInt remainingLength; |
| 55 | char qos = 0; | 49 | char qos = 0; |
| 56 | std::shared_ptr<Client> sender; | 50 | std::shared_ptr<Client> sender; |
| 57 | char first_byte = 0; | 51 | char first_byte = 0; |
| @@ -115,8 +109,6 @@ public: | @@ -115,8 +109,6 @@ public: | ||
| 115 | std::shared_ptr<Client> getSender() const; | 109 | std::shared_ptr<Client> getSender() const; |
| 116 | void setSender(const std::shared_ptr<Client> &value); | 110 | void setSender(const std::shared_ptr<Client> &value); |
| 117 | bool containsFixedHeader() const; | 111 | bool containsFixedHeader() const; |
| 118 | - char getFirstByte() const; | ||
| 119 | - RemainingLength getRemainingLength() const; | ||
| 120 | void setPacketId(uint16_t packet_id); | 112 | void setPacketId(uint16_t packet_id); |
| 121 | uint16_t getPacketId() const; | 113 | uint16_t getPacketId() const; |
| 122 | void setDuplicate(); | 114 | void setDuplicate(); |
variablebyteint.cpp
0 → 100644
| 1 | +#include "variablebyteint.h" | ||
| 2 | + | ||
| 3 | +#include <cassert> | ||
| 4 | +#include <cstring> | ||
| 5 | +#include <stdexcept> | ||
| 6 | + | ||
| 7 | +void VariableByteInt::readIntoBuf(CirBuf &buf) const | ||
| 8 | +{ | ||
| 9 | + assert(len > 0); | ||
| 10 | + buf.write(bytes, len); | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +VariableByteInt &VariableByteInt::operator=(uint32_t x) | ||
| 14 | +{ | ||
| 15 | + if (x > 268435455) | ||
| 16 | + throw std::runtime_error("Value of variable byte int to encode too big. Bug or corrupt packet?"); | ||
| 17 | + | ||
| 18 | + len = 0; | ||
| 19 | + | ||
| 20 | + do | ||
| 21 | + { | ||
| 22 | + uint8_t encodedByte = x % 128; | ||
| 23 | + x = x / 128; | ||
| 24 | + if (x > 0) | ||
| 25 | + encodedByte = encodedByte | 128; | ||
| 26 | + bytes[len++] = encodedByte; | ||
| 27 | + } | ||
| 28 | + while(x > 0); | ||
| 29 | + | ||
| 30 | + return *this; | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +uint8_t VariableByteInt::getLen() const | ||
| 34 | +{ | ||
| 35 | + return len; | ||
| 36 | +} |
variablebyteint.h
0 → 100644
| 1 | +#ifndef VARIABLEBYTEINT_H | ||
| 2 | +#define VARIABLEBYTEINT_H | ||
| 3 | + | ||
| 4 | +#include "cirbuf.h" | ||
| 5 | + | ||
| 6 | +class VariableByteInt | ||
| 7 | +{ | ||
| 8 | + char bytes[4]; | ||
| 9 | + uint8_t len = 0; | ||
| 10 | + | ||
| 11 | +public: | ||
| 12 | + void readIntoBuf(CirBuf &buf) const; | ||
| 13 | + VariableByteInt &operator=(uint32_t x); | ||
| 14 | + uint8_t getLen() const; | ||
| 15 | +}; | ||
| 16 | + | ||
| 17 | +#endif // VARIABLEBYTEINT_H |