/*
* Copyright (c) 2009, 2012 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Dave Locke - initial API and implementation and/or initial documentation
*/
package org.eclipse.paho.client.mqttv3.internal.wire;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
/**
* An on-the-wire representation of an MQTT SEND message.
*/
public class MqttPublish extends MqttPersistableWireMessage {
private MqttMessage message;
private String topicName;
private byte[] encodedPayload = null;
public MqttPublish(String name, MqttMessage message) {
super(MqttWireMessage.MESSAGE_TYPE_PUBLISH);
this.topicName = name;
this.message = message;
}
/**
* Constructs a new MqttPublish object.
* @param info the message info byte
* @param data the variable header and payload bytes
*/
public MqttPublish(byte info, byte[] data) throws MqttException, IOException {
super(MqttWireMessage.MESSAGE_TYPE_PUBLISH);
this.message = new MqttReceivedMessage();
message.setQos((info >> 1) & 0x03);
if ((info & 0x01) == 0x01) {
message.setRetained(true);
}
if ((info & 0x08) == 0x08) {
((MqttReceivedMessage) message).setDuplicate(true);
}
ByteArrayInputStream bais = new ByteArrayInputStream(data);
CountingInputStream counter = new CountingInputStream(bais);
DataInputStream dis = new DataInputStream(counter);
topicName = this.decodeUTF8(dis);
if (message.getQos() > 0) {
msgId = dis.readUnsignedShort();
}
byte[] payload = new byte[data.length-counter.getCounter()];
dis.readFully(payload);
dis.close();
message.setPayload(payload);
}
protected byte getMessageInfo() {
byte info = (byte) (message.getQos() << 1);
if (message.isRetained()) {
info |= 0x01;
}
if (message.isDuplicate() || duplicate ) {
info |= 0x08;
}
return info;
}
public String getTopicName() {
return topicName;
}
public MqttMessage getMessage() {
return message;
}
protected static byte[] encodePayload(MqttMessage message) {
return message.getPayload();
}
public byte[] getPayload() throws MqttException {
if (encodedPayload == null) {
encodedPayload = encodePayload(message);
}
return encodedPayload;
}
public int getPayloadLength() {
int length = 0;
try {
length = getPayload().length;
} catch(MqttException me) {
}
return length;
}
public void setMessageId(int msgId) {
super.setMessageId(msgId);
if (message instanceof MqttReceivedMessage) {
((MqttReceivedMessage)message).setMessageId(msgId);
}
}
protected byte[] getVariableHeader() throws MqttException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
this.encodeUTF8(dos, topicName);
if (message.getQos() > 0) {
dos.writeShort(msgId);
}
dos.flush();
return baos.toByteArray();
}
catch (IOException ex) {
throw new MqttException(ex);
}
}
public boolean isMessageIdRequired() {
// all publishes require a message ID as it's used as the key to the token store
return true;
}
}