com.github.sylvek.wsmqttfwd.decoder.PublishDecoder.java Source code

Java tutorial

Introduction

Here is the source code for com.github.sylvek.wsmqttfwd.decoder.PublishDecoder.java

Source

/*
 * Copyright (c) 2012-2015 The original author or authors
 * ------------------------------------------------------
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 *
 * The Eclipse Public License is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * The Apache License v2.0 is available at
 * http://www.opensource.org/licenses/apache2.0.php
 *
 * You may elect to redistribute this code under either of these licenses.
 */
package com.github.sylvek.wsmqttfwd.decoder;

import com.github.sylvek.wsmqttfwd.message.PublishMessage;
import com.github.sylvek.wsmqttfwd.message.AbstractMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.CorruptedFrameException;
import io.netty.util.AttributeMap;

/**
 * @author andrea
 * @author Sylvain Maucourt
 */
public class PublishDecoder extends DemuxDecoder<PublishMessage> {

    private static Logger LOG = LoggerFactory.getLogger(PublishDecoder.class);

    @Override
    public PublishMessage decode(AttributeMap ctx, ByteBuf in) throws Exception {
        LOG.debug("decode invoked with buffer {}", in);
        in.resetReaderIndex();
        int startPos = in.readerIndex();

        //Common decoding part
        PublishMessage message = new PublishMessage();
        if (!decodeCommonHeader(message, in)) {
            LOG.debug("decode ask for more data after {}", in);
            in.resetReaderIndex();
            return null;
        }

        int remainingLength = message.getRemainingLength();

        //Topic name
        String topic = Utils.decodeString(in);
        if (topic == null) {
            in.resetReaderIndex();
            return null;
        }
        //[MQTT-3.3.2-2] The Topic Name in the PUBLISH Packet MUST NOT contain wildcard characters.
        if (topic.contains("+") || topic.contains("#")) {
            throw new CorruptedFrameException(
                    "Received a PUBLISH with topic containing wild card chars, topic: " + topic);
        }
        //check topic is at least one char [MQTT-4.7.3-1]
        if (topic.length() == 0) {
            throw new CorruptedFrameException("Received a PUBLISH with topic without any character");
        }

        message.setTopicName(topic);

        if (message.getQos() == AbstractMessage.QOSType.LEAST_ONE
                || message.getQos() == AbstractMessage.QOSType.EXACTLY_ONCE) {
            message.setMessageID(in.readUnsignedShort());
        }
        int stopPos = in.readerIndex();

        //read the payload
        int payloadSize = remainingLength - (stopPos - startPos - 2)
                + (Utils.numBytesToEncode(remainingLength) - 1);
        if (in.readableBytes() < payloadSize) {
            in.resetReaderIndex();
            return null;
        }
        ByteBuf bb = Unpooled.buffer(payloadSize);
        in.readBytes(bb);
        message.setPayload(bb.nioBuffer());

        return message;
    }
}