diff --git a/src/zutil/net/mqtt/packet/MqttPacketPublish.java b/src/zutil/net/mqtt/packet/MqttPacketPublish.java
index 6432148..c67e026 100755
--- a/src/zutil/net/mqtt/packet/MqttPacketPublish.java
+++ b/src/zutil/net/mqtt/packet/MqttPacketPublish.java
@@ -89,15 +89,14 @@ public class MqttPacketPublish extends MqttPacketHeader {
// ------------------------------------------
// - Application data
- @CustomBinaryField(index = 3000, serializer = MqttPacketPublishPayloadSerializer.class)
- public byte[] payload;
-
-
@Override
public int calculatePayloadLength() {
return payload == null ? 0 : payload.length;
}
+ @CustomBinaryField(index = 3000, serializer = MqttPacketPublishPayloadSerializer.class)
+ public byte[] payload;
+
// ------------------------------------------
// Util methods
// ------------------------------------------
diff --git a/src/zutil/net/mqtt/packet/MqttVariableIntSerializer.java b/src/zutil/net/mqtt/packet/MqttVariableIntSerializer.java
index 10bd06f..0fb1b44 100755
--- a/src/zutil/net/mqtt/packet/MqttVariableIntSerializer.java
+++ b/src/zutil/net/mqtt/packet/MqttVariableIntSerializer.java
@@ -33,6 +33,7 @@ import java.io.OutputStream;
/**
* Code from MQTT specification
+ * @see 2.2.3 Remaining Length (variable length encoding scheme)
*/
public class MqttVariableIntSerializer implements BinaryFieldSerializer {
@@ -60,7 +61,7 @@ public class MqttVariableIntSerializer implements BinaryFieldSerializer
x = x / 128;
// if there are more data to encode, set the top bit of this byte
if (x > 0)
- encodedByte = encodedByte & 128;
+ encodedByte = encodedByte | 128;
out.write(encodedByte);
} while (x > 0);
}
diff --git a/test/zutil/net/mqtt/packet/MqttPacketPublishTest.java b/test/zutil/net/mqtt/packet/MqttPacketPublishTest.java
index bd02164..0de495e 100644
--- a/test/zutil/net/mqtt/packet/MqttPacketPublishTest.java
+++ b/test/zutil/net/mqtt/packet/MqttPacketPublishTest.java
@@ -8,6 +8,7 @@ import zutil.parser.binary.BinaryStructOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import static org.junit.Assert.*;
@@ -159,4 +160,59 @@ public class MqttPacketPublishTest {
MqttPacket.write(binOut, obj);
assertArrayEquals(Converter.toBytes(data), buffer.toByteArray());
}
+
+ @Test
+ public void encodeQos2() throws IOException {
+ char[] data = new char[]{
+ // Fixed Header
+ 0b0011_0100, // Packet Type(4) + Reserved(4)
+ 0xFF & 6, // Variable Header + Payload Length
+ // Variable Header
+ 0b0000_0000, // length
+ 0xFF & 2, // length
+ 'a', // Topic Name
+ 'b', // Topic Name
+ 0b0000_0000, // Packet ID
+ 0b0000_0101 // Packet ID
+ // Payload
+ };
+
+ MqttPacketPublish obj = new MqttPacketPublish();
+ obj.setFlagQoS(MqttPacketPublish.PUBLISH_QOS_2);
+ obj.topicName = "ab";
+ obj.packetId = 5;
+
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ BinaryStructOutputStream binOut = new BinaryStructOutputStream(buffer);
+ MqttPacket.write(binOut, obj);
+ assertArrayEquals(Converter.toBytes(data), buffer.toByteArray());
+ }
+
+ @Test
+ public void encodePayloadStream() throws IOException {
+ char[] data = new char[]{
+ // Fixed Header
+ 0b0011_0000, // Packet Type(4) + Reserved(4)
+ 0xFF & 8, // Variable Header + Payload Length
+ // Variable Header
+ 0b0000_0000, // length
+ 0xFF & 2, // length
+ 'a', // Topic Name
+ 'b', // Topic Name
+ // Payload
+ 't', 'e', 's', 't',
+
+ };
+
+ MqttPacketPublish obj = new MqttPacketPublish();
+ obj.topicName = "ab";
+ obj.payload = "test".getBytes(StandardCharsets.UTF_8);
+
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ BinaryStructOutputStream binOut = new BinaryStructOutputStream(buffer);
+
+ MqttPacket.write(binOut, obj);
+
+ assertArrayEquals(Converter.toBytes(data), buffer.toByteArray());
+ }
}
\ No newline at end of file
diff --git a/test/zutil/net/mqtt/packet/MqttVariableIntSerializerTest.java b/test/zutil/net/mqtt/packet/MqttVariableIntSerializerTest.java
new file mode 100644
index 0000000..fc075c4
--- /dev/null
+++ b/test/zutil/net/mqtt/packet/MqttVariableIntSerializerTest.java
@@ -0,0 +1,79 @@
+package zutil.net.mqtt.packet;
+
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class MqttVariableIntSerializerTest {
+
+ @Test
+ public void read() throws IOException {
+ MqttVariableIntSerializer serializer = new MqttVariableIntSerializer();
+
+ int actual = serializer.read(new ByteArrayInputStream(new byte[]{0x0}), null);
+ assertEquals(0, actual);
+
+ actual = serializer.read(new ByteArrayInputStream(new byte[]{0x7f}), null);
+ assertEquals(127, actual);
+
+ actual = serializer.read(new ByteArrayInputStream(new byte[]{(byte)0x80, 0x01}), null);
+ assertEquals(128, actual);
+
+ actual = serializer.read(new ByteArrayInputStream(new byte[]{(byte)0xFF, 0x7f}), null);
+ assertEquals(16_383, actual);
+
+ actual = serializer.read(new ByteArrayInputStream(new byte[]{(byte)0x80, (byte)0x80, 0x01}), null);
+ assertEquals(16_384, actual);
+
+ actual = serializer.read(new ByteArrayInputStream(new byte[]{(byte)0xFF, (byte)0xFF, 0x7f}), null);
+ assertEquals(2_097_151, actual);
+
+ actual = serializer.read(new ByteArrayInputStream(new byte[]{(byte)0x80, (byte)0x80, (byte)0x80, 0x01}), null);
+ assertEquals(2_097_152, actual);
+
+ actual = serializer.read(new ByteArrayInputStream(new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF, 0x7f}), null);
+ assertEquals(268_435_455, actual);
+ }
+
+ @Test
+ public void write() throws IOException {
+ MqttVariableIntSerializer serializer = new MqttVariableIntSerializer();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.reset();
+ serializer.write(out, 0, null);
+ assertArrayEquals(new byte[]{0x0}, out.toByteArray());
+
+ out.reset();
+ serializer.write(out, 127, null);
+ assertArrayEquals(new byte[]{0x7F}, out.toByteArray());
+
+ out.reset();
+ serializer.write(out, 128, null);
+ assertArrayEquals(new byte[]{(byte)0x80, 0x01}, out.toByteArray());
+
+ out.reset();
+ serializer.write(out, 16_383, null);
+ assertArrayEquals(new byte[]{(byte)0xFF, 0x7f}, out.toByteArray());
+
+ out.reset();
+ serializer.write(out, 16_384, null);
+ assertArrayEquals(new byte[]{(byte)0x80, (byte)0x80, 0x01}, out.toByteArray());
+
+ out.reset();
+ serializer.write(out, 2_097_151, null);
+ assertArrayEquals(new byte[]{(byte)0xFF, (byte)0xFF, 0x7f}, out.toByteArray());
+
+ out.reset();
+ serializer.write(out, 2_097_152, null);
+ assertArrayEquals(new byte[]{(byte)0x80, (byte)0x80, (byte)0x80, 0x01}, out.toByteArray());
+
+ out.reset();
+ serializer.write(out, 268_435_455, null);
+ assertArrayEquals(new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF, 0x7f}, out.toByteArray());
+ }
+}
\ No newline at end of file