Example usage for io.netty.buffer ByteBuf readBytes

List of usage examples for io.netty.buffer ByteBuf readBytes

Introduction

In this page you can find the example usage for io.netty.buffer ByteBuf readBytes.

Prototype

public abstract int readBytes(FileChannel out, long position, int length) throws IOException;

Source Link

Document

Transfers this buffer's data starting at the current readerIndex to the specified channel starting at the given file position.

Usage

From source file:com.codeabovelab.dm.platform.http.async.ByteBufHolderAdapter.java

License:Apache License

@Override
public int readBytes(ByteBufHolder chunk, byte[] arr, int off, int len) {
    ByteBuf buf = chunk.content();
    int avail = buf.readableBytes();
    if (avail == 0) {
        return ChunkedInputStream.EOF;
    }//from  w  ww . j a v a 2  s . c  om
    int readed = Math.min(len, avail);
    buf.readBytes(arr, off, readed);
    return readed;
}

From source file:com.flowpowered.network.processor.simple.SimpleMessageProcessor.java

License:MIT License

@Override
public final synchronized ByteBuf processOutbound(ChannelHandlerContext ctx, final ByteBuf input,
        ByteBuf buffer) {//from  w w w  . j  a va  2s  . c  o  m
    int remaining;
    while ((remaining = input.readableBytes()) > 0) {
        int clamped = Math.min(remaining, capacity);
        input.readBytes(encodingByteBuffer, 0, clamped);
        writeEncode(encodingByteBuffer, clamped);
        int read;
        while ((read = readEncode(encodingByteBuffer)) > 0) {
            buffer.writeBytes(encodingByteBuffer, 0, read);
        }
    }
    return buffer;
}

From source file:com.flowpowered.network.processor.simple.SimpleMessageProcessor.java

License:MIT License

@Override
public final synchronized ByteBuf processInbound(ChannelHandlerContext ctx, final ByteBuf input,
        ByteBuf buffer) {/*from www .  j a v  a  2 s .  com*/
    int remaining;
    while ((remaining = input.readableBytes()) > 0) {
        int clamped = Math.min(remaining, capacity);
        input.readBytes(decodingByteBuffer, 0, clamped);
        writeDecode(decodingByteBuffer, clamped);
        int read;
        while ((read = readDecode(decodingByteBuffer)) > 0) {
            buffer.writeBytes(decodingByteBuffer, 0, read);
        }
    }
    return buffer;
}

From source file:com.github.lburgazzoli.quickfixj.transport.netty.codec.NettyRegExMessageDecoder.java

License:Apache License

/**
 *
 * @param in/*from w  w  w  . jav a2 s.c o  m*/
 * @return
 * @throws Exception
 */
private Object doDecodeBuffer(ByteBuf in) throws Exception {
    byte[] rv = null;
    int rindex = in.readerIndex();
    String bs = in.toString();
    Matcher mh = FIXCodecHelper.getCodecMatcher(bs);
    boolean reset = true;

    in.readerIndex(rindex);

    if (mh.find() && (mh.groupCount() == 4)) {
        int offset = mh.start(0);
        int size = mh.end(4) - mh.start(0) + 1;

        rv = new byte[size];
        reset = false;

        in.readBytes(rv, offset, size);
        in.readerIndex(mh.end(4) + 1);
    }

    if (reset) {
        in.readerIndex(rindex);
    }

    return rv;
}

From source file:com.heliosapm.utils.buffer.BufferManager.java

License:Apache License

/**
 * Reads a UTF string from the passed ByteBuff
 * @param in The ByteBuf to read from/*from w ww . java2s  .c  om*/
 * @return the read string
 */
public final static String readUTF(final ByteBuf in) {
    try {
        int utflen = in.readUnsignedShort();
        byte[] bytearr = new byte[utflen];
        char[] chararr = new char[utflen];
        int c, char2, char3;
        int count = 0;
        int chararr_count = 0;
        in.readBytes(bytearr, 0, utflen);

        while (count < utflen) {
            c = bytearr[count] & 0xff;
            if (c > 127)
                break;
            count++;
            chararr[chararr_count++] = (char) c;
        }

        while (count < utflen) {
            c = bytearr[count] & 0xff;
            switch (c >> 4) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                /* 0xxxxxxx*/
                count++;
                chararr[chararr_count++] = (char) c;
                break;
            case 12:
            case 13:
                /* 110x xxxx   10xx xxxx*/
                count += 2;
                if (count > utflen)
                    throw new UTFDataFormatException("malformed input: partial character at end");
                char2 = bytearr[count - 1];
                if ((char2 & 0xC0) != 0x80)
                    throw new UTFDataFormatException("malformed input around byte " + count);
                chararr[chararr_count++] = (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
            case 14:
                /* 1110 xxxx  10xx xxxx  10xx xxxx */
                count += 3;
                if (count > utflen)
                    throw new UTFDataFormatException("malformed input: partial character at end");
                char2 = bytearr[count - 2];
                char3 = bytearr[count - 1];
                if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
                    throw new UTFDataFormatException("malformed input around byte " + (count - 1));
                chararr[chararr_count++] = (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6)
                        | ((char3 & 0x3F) << 0));
                break;
            default:
                /* 10xx xxxx,  1111 xxxx */
                throw new UTFDataFormatException("malformed input around byte " + count);
            }
        }
        // The number of chars produced may be less than utflen
        return new String(chararr, 0, chararr_count);
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

From source file:com.mnt.base.stream.netty.NStreamLightweightParser.java

License:Open Source License

public void read(ByteBuf byteBuffer) throws Exception {

    // Check that the buffer is not bigger than 100 Megabyte. For security reasons
    // we will abort parsing when 100 MB of queued byte was found.
    if (buffer.size() > maxBufferSize) {
        throw new Exception("Stopped parsing never ending stream");
    }/*from w  w  w . ja v  a  2 s .com*/

    int len = byteBuffer.readableBytes();

    if (len > 0) {
        byte[] bytes = new byte[len];
        byteBuffer.readBytes(bytes, 0, len);
        readBytes(bytes, 0);
    }
}

From source file:com.mobius.software.android.iotbroker.mqtt.parser.MQParser.java

License:Open Source License

public static MQMessage decode(ByteBuf buf) throws MalformedMessageException, UnsupportedEncodingException {
    MQMessage header = null;/*www .j a  v a  2 s  .c  om*/

    byte fixedHeader = buf.readByte();

    LengthDetails length = decodeLength(buf);

    MessageType type = MessageType.valueOf((fixedHeader >> 4) & 0xf);
    switch (type) {
    case CONNECT:

        byte[] nameValue = new byte[buf.readUnsignedShort()];
        buf.readBytes(nameValue, 0, nameValue.length);
        String name = new String(nameValue, "UTF-8");
        if (!name.equals("MQTT"))
            throw new MalformedMessageException("CONNECT, protocol-name set to " + name);

        int protocolLevel = buf.readUnsignedByte();

        byte contentFlags = buf.readByte();

        boolean userNameFlag = (((contentFlags >> 7) & 1) == 1) ? true : false;
        boolean userPassFlag = (((contentFlags >> 6) & 1) == 1) ? true : false;
        boolean willRetain = (((contentFlags >> 5) & 1) == 1) ? true : false;
        QoS willQos = QoS.valueOf(((contentFlags & 0x1f) >> 3) & 3);
        if (willQos == null)
            throw new MalformedMessageException("CONNECT, will QoS set to " + willQos);
        boolean willFlag = (((contentFlags >> 2) & 1) == 1) ? true : false;

        if (willQos.getValue() > 0 && !willFlag)
            throw new MalformedMessageException("CONNECT, will QoS set to " + willQos + ", willFlag not set");

        if (willRetain && !willFlag)
            throw new MalformedMessageException("CONNECT, will retain set, willFlag not set");

        boolean cleanSession = (((contentFlags >> 1) & 1) == 1) ? true : false;

        boolean reservedFlag = ((contentFlags & 1) == 1) ? true : false;
        if (reservedFlag)
            throw new MalformedMessageException("CONNECT, reserved flag set to true");

        int keepalive = buf.readUnsignedShort();

        byte[] clientIdValue = new byte[buf.readUnsignedShort()];
        buf.readBytes(clientIdValue, 0, clientIdValue.length);
        String clientID = new String(clientIdValue, "UTF-8");
        if (!StringVerifier.verify(clientID))
            throw new MalformedMessageException(
                    "ClientID contains restricted characters: U+0000, U+D000-U+DFFF");

        Text willTopic = null;
        byte[] willMessage = null;
        String username = null;
        String password = null;

        Will will = null;
        if (willFlag) {
            if (buf.readableBytes() < 2)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            byte[] willTopicValue = new byte[buf.readUnsignedShort()];
            if (buf.readableBytes() < willTopicValue.length)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            buf.readBytes(willTopicValue, 0, willTopicValue.length);

            String willTopicName = new String(willTopicValue, "UTF-8");
            if (!StringVerifier.verify(willTopicName))
                throw new MalformedMessageException(
                        "WillTopic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
            willTopic = new Text(willTopicName);

            if (buf.readableBytes() < 2)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            willMessage = new byte[buf.readUnsignedShort()];
            if (buf.readableBytes() < willMessage.length)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            buf.readBytes(willMessage, 0, willMessage.length);
            if (willTopic.length() == 0)
                throw new MalformedMessageException("invalid will encoding");
            will = new Will(new Topic(willTopic, willQos), willMessage, willRetain);
            if (!will.isValid())
                throw new MalformedMessageException("invalid will encoding");
        }

        if (userNameFlag) {
            if (buf.readableBytes() < 2)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            byte[] userNameValue = new byte[buf.readUnsignedShort()];
            if (buf.readableBytes() < userNameValue.length)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            buf.readBytes(userNameValue, 0, userNameValue.length);
            username = new String(userNameValue, "UTF-8");
            if (!StringVerifier.verify(username))
                throw new MalformedMessageException(
                        "Username contains one or more restricted characters: U+0000, U+D000-U+DFFF");
        }

        if (userPassFlag) {
            if (buf.readableBytes() < 2)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            byte[] userPassValue = new byte[buf.readUnsignedShort()];
            if (buf.readableBytes() < userPassValue.length)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            buf.readBytes(userPassValue, 0, userPassValue.length);
            password = new String(userPassValue, "UTF-8");
            if (!StringVerifier.verify(password))
                throw new MalformedMessageException(
                        "Password contains one or more restricted characters: U+0000, U+D000-U+DFFF");
        }

        if (buf.readableBytes() > 0)
            throw new MalformedMessageException("Invalid encoding will/username/password");

        Connect connect = new Connect(username, password, clientID, cleanSession, keepalive, will);
        if (protocolLevel != 4)
            connect.setProtocolLevel(protocolLevel);
        header = connect;
        break;

    case CONNACK:
        byte sessionPresentValue = buf.readByte();
        if (sessionPresentValue != 0 && sessionPresentValue != 1)
            throw new MalformedMessageException(
                    String.format("CONNACK, session-present set to %d", sessionPresentValue & 0xff));
        boolean isPresent = sessionPresentValue == 1 ? true : false;

        short connackByte = buf.readUnsignedByte();
        ConnackCode connackCode = ConnackCode.valueOf(connackByte);
        if (connackCode == null)
            throw new MalformedMessageException("Invalid connack code: " + connackByte);
        header = new Connack(isPresent, connackCode);
        break;

    case PUBLISH:
        int dataLength = length.getLength();
        fixedHeader &= 0xf;

        boolean dup = (((fixedHeader >> 3) & 1) == 1) ? true : false;

        QoS qos = QoS.valueOf((fixedHeader & 0x07) >> 1);
        if (qos == null)
            throw new MalformedMessageException("invalid QoS value");
        if (dup && qos == QoS.AT_MOST_ONCE)
            throw new MalformedMessageException("PUBLISH, QoS-0 dup flag present");

        boolean retain = ((fixedHeader & 1) == 1) ? true : false;

        byte[] topicNameValue = new byte[buf.readUnsignedShort()];
        buf.readBytes(topicNameValue, 0, topicNameValue.length);
        String topicName = new String(topicNameValue, "UTF-8");
        if (!StringVerifier.verify(topicName))
            throw new MalformedMessageException(
                    "Publish-topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
        dataLength -= topicName.length() + 2;

        Integer packetID = null;
        if (qos != QoS.AT_MOST_ONCE) {
            packetID = buf.readUnsignedShort();
            if (packetID < 0 || packetID > 65535)
                throw new MalformedMessageException("Invalid PUBLISH packetID encoding");
            dataLength -= 2;
        }
        byte[] data = new byte[dataLength];
        if (dataLength > 0)
            buf.readBytes(data, 0, data.length);
        header = new Publish(packetID, new Topic(new Text(topicName), qos), data, retain, dup);
        break;

    case PUBACK:
        header = new Puback(buf.readUnsignedShort());
        break;

    case PUBREC:
        header = new Pubrec(buf.readUnsignedShort());
        break;

    case PUBREL:
        header = new Pubrel(buf.readUnsignedShort());
        break;

    case PUBCOMP:
        header = new Pubcomp(buf.readUnsignedShort());
        break;

    case SUBSCRIBE:
        Integer subID = buf.readUnsignedShort();
        List<Topic> subscriptions = new ArrayList<Topic>();
        while (buf.isReadable()) {
            byte[] value = new byte[buf.readUnsignedShort()];
            buf.readBytes(value, 0, value.length);
            QoS requestedQos = QoS.valueOf(buf.readByte());
            if (requestedQos == null)
                throw new MalformedMessageException(
                        "Subscribe qos must be in range from 0 to 2: " + requestedQos);
            String topic = new String(value, "UTF-8");
            if (!StringVerifier.verify(topic))
                throw new MalformedMessageException(
                        "Subscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
            Topic subscription = new Topic(new Text(topic), requestedQos);
            subscriptions.add(subscription);
        }
        if (subscriptions.isEmpty())
            throw new MalformedMessageException("Subscribe with 0 topics");

        header = new Subscribe(subID, subscriptions.toArray(new Topic[subscriptions.size()]));
        break;

    case SUBACK:
        Integer subackID = buf.readUnsignedShort();
        List<SubackCode> subackCodes = new ArrayList<SubackCode>();
        while (buf.isReadable()) {
            short subackByte = buf.readUnsignedByte();
            SubackCode subackCode = SubackCode.valueOf(subackByte);
            if (subackCode == null)
                throw new MalformedMessageException("Invalid suback code: " + subackByte);
            subackCodes.add(subackCode);
        }
        if (subackCodes.isEmpty())
            throw new MalformedMessageException("Suback with 0 return-codes");

        header = new Suback(subackID, subackCodes);
        break;

    case UNSUBSCRIBE:
        Integer unsubID = buf.readUnsignedShort();
        List<Topic> unsubscribeTopics = new ArrayList<Topic>();
        while (buf.isReadable()) {
            byte[] value = new byte[buf.readUnsignedShort()];
            buf.readBytes(value, 0, value.length);
            String topic = new String(value, "UTF-8");
            if (!StringVerifier.verify(topic))
                throw new MalformedMessageException(
                        "Unsubscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
            Topic subscription = new Topic(new Text(topic), QoS.AT_MOST_ONCE);
            unsubscribeTopics.add(subscription);
        }
        if (unsubscribeTopics.isEmpty())
            throw new MalformedMessageException("Unsubscribe with 0 topics");

        header = new Unsubscribe(unsubID, unsubscribeTopics.toArray(new Topic[unsubscribeTopics.size()]));
        break;

    case UNSUBACK:
        header = new Unsuback(buf.readUnsignedShort());
        break;

    case PINGREQ:
        header = new Pingreq();
        break;
    case PINGRESP:
        header = new Pingresp();
        break;
    case DISCONNECT:
        header = new Disconnect();
        break;

    default:
        throw new MalformedMessageException("Invalid header type: " + type);
    }

    if (buf.isReadable())
        throw new MalformedMessageException("unexpected bytes in content");

    if (length.getLength() != header.getLength())
        throw new MalformedMessageException(String.format("Invalid length. Encoded: %d, actual: %d",
                length.getLength(), header.getLength()));

    return header;
}

From source file:com.mobius.software.mqtt.parser.MQParser.java

License:Open Source License

public MQMessage decodeUsingCache(ByteBuf buf) throws MalformedMessageException {
    byte fixedHeader = buf.readByte();

    LengthDetails length = LengthDetails.decode(buf);

    MessageType type = MessageType.valueOf((fixedHeader >> 4) & 0xf);
    MQMessage header = cache.borrowMessage(type);
    try {//from  www  .j  a  v  a  2  s . co  m
        switch (type) {
        case CONNECT:

            byte[] nameValue = new byte[buf.readUnsignedShort()];
            buf.readBytes(nameValue, 0, nameValue.length);
            String name = new String(nameValue, "UTF-8");
            if (!name.equals("MQTT"))
                throw new MalformedMessageException("CONNECT, protocol-name set to " + name);

            int protocolLevel = buf.readUnsignedByte();

            byte contentFlags = buf.readByte();

            boolean userNameFlag = ((contentFlags >> 7) & 1) == 1 ? true : false;
            boolean userPassFlag = ((contentFlags >> 6) & 1) == 1 ? true : false;
            boolean willRetain = ((contentFlags >> 5) & 1) == 1 ? true : false;
            QoS willQos = QoS.valueOf(((contentFlags & 0x1f) >> 3) & 3);
            if (willQos == null)
                throw new MalformedMessageException("CONNECT, will QoS set to " + willQos);
            boolean willFlag = (((contentFlags >> 2) & 1) == 1) ? true : false;

            if (willQos.getValue() > 0 && !willFlag)
                throw new MalformedMessageException(
                        "CONNECT, will QoS set to " + willQos + ", willFlag not set");

            if (willRetain && !willFlag)
                throw new MalformedMessageException("CONNECT, will retain set, willFlag not set");

            boolean cleanSession = ((contentFlags >> 1) & 1) == 1 ? true : false;

            boolean reservedFlag = (contentFlags & 1) == 1 ? true : false;
            if (reservedFlag)
                throw new MalformedMessageException("CONNECT, reserved flag set to true");

            int keepalive = buf.readUnsignedShort();

            byte[] clientIdValue = new byte[buf.readUnsignedShort()];
            buf.readBytes(clientIdValue, 0, clientIdValue.length);
            String clientID = new String(clientIdValue, "UTF-8");
            if (!StringVerifier.verify(clientID))
                throw new MalformedMessageException(
                        "ClientID contains restricted characters: U+0000, U+D000-U+DFFF");

            Text willTopic = null;
            byte[] willMessage = null;
            String username = null;
            String password = null;

            Will will = null;
            if (willFlag) {
                if (buf.readableBytes() < 2)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                byte[] willTopicValue = new byte[buf.readUnsignedShort()];
                if (buf.readableBytes() < willTopicValue.length)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                buf.readBytes(willTopicValue, 0, willTopicValue.length);

                String willTopicName = new String(willTopicValue, "UTF-8");
                if (!StringVerifier.verify(willTopicName))
                    throw new MalformedMessageException(
                            "WillTopic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
                willTopic = new Text(willTopicName);

                if (buf.readableBytes() < 2)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                willMessage = new byte[buf.readUnsignedShort()];
                if (buf.readableBytes() < willMessage.length)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                buf.readBytes(willMessage, 0, willMessage.length);
                if (willTopic.length() == 0)
                    throw new MalformedMessageException("invalid will encoding");
                will = new Will(new Topic(willTopic, willQos), willMessage, willRetain);
                if (!will.isValid())
                    throw new MalformedMessageException("invalid will encoding");
            }

            if (userNameFlag) {
                if (buf.readableBytes() < 2)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                byte[] userNameValue = new byte[buf.readUnsignedShort()];
                if (buf.readableBytes() < userNameValue.length)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                buf.readBytes(userNameValue, 0, userNameValue.length);
                username = new String(userNameValue, "UTF-8");
                if (!StringVerifier.verify(username))
                    throw new MalformedMessageException(
                            "Username contains one or more restricted characters: U+0000, U+D000-U+DFFF");
            }

            if (userPassFlag) {
                if (buf.readableBytes() < 2)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                byte[] userPassValue = new byte[buf.readUnsignedShort()];
                if (buf.readableBytes() < userPassValue.length)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                buf.readBytes(userPassValue, 0, userPassValue.length);
                password = new String(userPassValue, "UTF-8");
                if (!StringVerifier.verify(password))
                    throw new MalformedMessageException(
                            "Password contains one or more restricted characters: U+0000, U+D000-U+DFFF");
            }

            if (buf.readableBytes() > 0)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            Connect connect = (Connect) header;
            connect.reInit(username, password, clientID, cleanSession, keepalive, will);
            connect.setProtocolLevel(protocolLevel);
            break;

        case CONNACK:
            byte sessionPresentValue = buf.readByte();
            if (sessionPresentValue != 0 && sessionPresentValue != 1)
                throw new MalformedMessageException(
                        String.format("CONNACK, session-present set to %d", sessionPresentValue & 0xff));
            boolean isPresent = sessionPresentValue == 1 ? true : false;

            short connackByte = buf.readUnsignedByte();
            ConnackCode connackCode = ConnackCode.valueOf(connackByte);
            if (connackCode == null)
                throw new MalformedMessageException("Invalid connack code: " + connackByte);
            Connack connack = (Connack) header;
            connack.reInit(isPresent, connackCode);
            break;

        case PUBLISH:

            fixedHeader &= 0xf;

            boolean dup = ((fixedHeader >> 3) & 1) == 1 ? true : false;

            QoS qos = QoS.valueOf((fixedHeader & 0x07) >> 1);
            if (qos == null)
                throw new MalformedMessageException("invalid QoS value");
            if (dup && qos == QoS.AT_MOST_ONCE)
                throw new MalformedMessageException("PUBLISH, QoS-0 dup flag present");

            boolean retain = ((fixedHeader & 1) == 1) ? true : false;

            byte[] topicNameValue = new byte[buf.readUnsignedShort()];
            buf.readBytes(topicNameValue, 0, topicNameValue.length);
            String topicName = new String(topicNameValue, "UTF-8");
            if (!StringVerifier.verify(topicName))
                throw new MalformedMessageException(
                        "Publish-topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");

            Integer packetID = null;
            if (qos != QoS.AT_MOST_ONCE) {
                packetID = buf.readUnsignedShort();
                if (packetID < 0 || packetID > 65535)
                    throw new MalformedMessageException("Invalid PUBLISH packetID encoding");
            }

            ByteBuf data = Unpooled.buffer(buf.readableBytes());
            data.writeBytes(buf);

            Publish publish = (Publish) header;
            publish.reInit(packetID, new Topic(new Text(topicName), qos), data, retain, dup);
            break;

        case PUBACK:
        case PUBREC:
        case PUBREL:
        case PUBCOMP:
        case UNSUBACK:
            CountableMessage countable = (CountableMessage) header;
            countable.reInit(buf.readUnsignedShort());
            break;

        case SUBSCRIBE:
            Integer subID = buf.readUnsignedShort();
            List<Topic> subscriptions = new ArrayList<>();
            while (buf.isReadable()) {
                byte[] value = new byte[buf.readUnsignedShort()];
                buf.readBytes(value, 0, value.length);
                QoS requestedQos = QoS.valueOf(buf.readByte());
                if (requestedQos == null)
                    throw new MalformedMessageException(
                            "Subscribe qos must be in range from 0 to 2: " + requestedQos);
                String topic = new String(value, "UTF-8");
                if (!StringVerifier.verify(topic))
                    throw new MalformedMessageException(
                            "Subscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
                Topic subscription = new Topic(new Text(topic), requestedQos);
                subscriptions.add(subscription);
            }
            if (subscriptions.isEmpty())
                throw new MalformedMessageException("Subscribe with 0 topics");

            Subscribe subscribe = (Subscribe) header;
            subscribe.reInit(subID, subscriptions.toArray(new Topic[subscriptions.size()]));
            break;

        case SUBACK:
            Integer subackID = buf.readUnsignedShort();
            List<SubackCode> subackCodes = new ArrayList<>();
            while (buf.isReadable()) {
                short subackByte = buf.readUnsignedByte();
                SubackCode subackCode = SubackCode.valueOf(subackByte);
                if (subackCode == null)
                    throw new MalformedMessageException("Invalid suback code: " + subackByte);
                subackCodes.add(subackCode);
            }
            if (subackCodes.isEmpty())
                throw new MalformedMessageException("Suback with 0 return-codes");

            Suback suback = (Suback) header;
            suback.reInit(subackID, subackCodes);
            break;

        case UNSUBSCRIBE:
            Integer unsubID = buf.readUnsignedShort();
            List<Text> unsubscribeTopics = new ArrayList<>();
            while (buf.isReadable()) {
                byte[] value = new byte[buf.readUnsignedShort()];
                buf.readBytes(value, 0, value.length);
                String topic = new String(value, "UTF-8");
                if (!StringVerifier.verify(topic))
                    throw new MalformedMessageException(
                            "Unsubscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
                unsubscribeTopics.add(new Text(topic));
            }
            if (unsubscribeTopics.isEmpty())
                throw new MalformedMessageException("Unsubscribe with 0 topics");
            Unsubscribe unsubscribe = (Unsubscribe) header;
            unsubscribe.reInit(unsubID, unsubscribeTopics.toArray(new Text[unsubscribeTopics.size()]));
            break;

        case PINGREQ:
        case PINGRESP:
        case DISCONNECT:
            break;

        default:
            throw new MalformedMessageException("Invalid header type: " + type);
        }

        if (buf.isReadable())
            throw new MalformedMessageException("unexpected bytes in content");

        if (length.getLength() != header.getLength())
            throw new MalformedMessageException(String.format("Invalid length. Encoded: %d, actual: %d",
                    length.getLength(), header.getLength()));

        return header;
    } catch (UnsupportedEncodingException e) {
        throw new MalformedMessageException("unsupported string encoding:" + e.getMessage());
    }
}

From source file:com.mobius.software.mqtt.parser.MQParser.java

License:Open Source License

public static MQMessage decode(ByteBuf buf) throws MalformedMessageException {
    MQMessage header = null;/* ww  w.  j a  v a  2s . c om*/

    byte fixedHeader = buf.readByte();

    LengthDetails length = LengthDetails.decode(buf);

    MessageType type = MessageType.valueOf((fixedHeader >> 4) & 0xf);
    try {
        switch (type) {
        case CONNECT:

            byte[] nameValue = new byte[buf.readUnsignedShort()];
            buf.readBytes(nameValue, 0, nameValue.length);
            String name = new String(nameValue, "UTF-8");
            if (!name.equals("MQTT"))
                throw new MalformedMessageException("CONNECT, protocol-name set to " + name);

            int protocolLevel = buf.readUnsignedByte();

            byte contentFlags = buf.readByte();

            boolean userNameFlag = ((contentFlags >> 7) & 1) == 1 ? true : false;
            boolean userPassFlag = ((contentFlags >> 6) & 1) == 1 ? true : false;
            boolean willRetain = ((contentFlags >> 5) & 1) == 1 ? true : false;
            QoS willQos = QoS.valueOf(((contentFlags & 0x1f) >> 3) & 3);
            if (willQos == null)
                throw new MalformedMessageException("CONNECT, will QoS set to " + willQos);
            boolean willFlag = (((contentFlags >> 2) & 1) == 1) ? true : false;

            if (willQos.getValue() > 0 && !willFlag)
                throw new MalformedMessageException(
                        "CONNECT, will QoS set to " + willQos + ", willFlag not set");

            if (willRetain && !willFlag)
                throw new MalformedMessageException("CONNECT, will retain set, willFlag not set");

            boolean cleanSession = ((contentFlags >> 1) & 1) == 1 ? true : false;

            boolean reservedFlag = (contentFlags & 1) == 1 ? true : false;
            if (reservedFlag)
                throw new MalformedMessageException("CONNECT, reserved flag set to true");

            int keepalive = buf.readUnsignedShort();

            byte[] clientIdValue = new byte[buf.readUnsignedShort()];
            buf.readBytes(clientIdValue, 0, clientIdValue.length);
            String clientID = new String(clientIdValue, "UTF-8");
            if (!StringVerifier.verify(clientID))
                throw new MalformedMessageException(
                        "ClientID contains restricted characters: U+0000, U+D000-U+DFFF");

            Text willTopic = null;
            byte[] willMessage = null;
            String username = null;
            String password = null;

            Will will = null;
            if (willFlag) {
                if (buf.readableBytes() < 2)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                byte[] willTopicValue = new byte[buf.readUnsignedShort()];
                if (buf.readableBytes() < willTopicValue.length)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                buf.readBytes(willTopicValue, 0, willTopicValue.length);

                String willTopicName = new String(willTopicValue, "UTF-8");
                if (!StringVerifier.verify(willTopicName))
                    throw new MalformedMessageException(
                            "WillTopic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
                willTopic = new Text(willTopicName);

                if (buf.readableBytes() < 2)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                willMessage = new byte[buf.readUnsignedShort()];
                if (buf.readableBytes() < willMessage.length)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                buf.readBytes(willMessage, 0, willMessage.length);
                if (willTopic.length() == 0)
                    throw new MalformedMessageException("invalid will encoding");
                will = new Will(new Topic(willTopic, willQos), willMessage, willRetain);
                if (!will.isValid())
                    throw new MalformedMessageException("invalid will encoding");
            }

            if (userNameFlag) {
                if (buf.readableBytes() < 2)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                byte[] userNameValue = new byte[buf.readUnsignedShort()];
                if (buf.readableBytes() < userNameValue.length)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                buf.readBytes(userNameValue, 0, userNameValue.length);
                username = new String(userNameValue, "UTF-8");
                if (!StringVerifier.verify(username))
                    throw new MalformedMessageException(
                            "Username contains one or more restricted characters: U+0000, U+D000-U+DFFF");
            }

            if (userPassFlag) {
                if (buf.readableBytes() < 2)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                byte[] userPassValue = new byte[buf.readUnsignedShort()];
                if (buf.readableBytes() < userPassValue.length)
                    throw new MalformedMessageException("Invalid encoding will/username/password");

                buf.readBytes(userPassValue, 0, userPassValue.length);
                password = new String(userPassValue, "UTF-8");
                if (!StringVerifier.verify(password))
                    throw new MalformedMessageException(
                            "Password contains one or more restricted characters: U+0000, U+D000-U+DFFF");
            }

            if (buf.readableBytes() > 0)
                throw new MalformedMessageException("Invalid encoding will/username/password");

            Connect connect = new Connect(username, password, clientID, cleanSession, keepalive, will);
            if (protocolLevel != 4)
                connect.setProtocolLevel(protocolLevel);
            header = connect;
            break;

        case CONNACK:
            byte sessionPresentValue = buf.readByte();
            if (sessionPresentValue != 0 && sessionPresentValue != 1)
                throw new MalformedMessageException(
                        String.format("CONNACK, session-present set to %d", sessionPresentValue & 0xff));
            boolean isPresent = sessionPresentValue == 1 ? true : false;

            short connackByte = buf.readUnsignedByte();
            ConnackCode connackCode = ConnackCode.valueOf(connackByte);
            if (connackCode == null)
                throw new MalformedMessageException("Invalid connack code: " + connackByte);
            header = new Connack(isPresent, connackCode);
            break;

        case PUBLISH:

            fixedHeader &= 0xf;

            boolean dup = ((fixedHeader >> 3) & 1) == 1 ? true : false;

            QoS qos = QoS.valueOf((fixedHeader & 0x07) >> 1);
            if (qos == null)
                throw new MalformedMessageException("invalid QoS value");
            if (dup && qos == QoS.AT_MOST_ONCE)
                throw new MalformedMessageException("PUBLISH, QoS-0 dup flag present");

            boolean retain = ((fixedHeader & 1) == 1) ? true : false;

            byte[] topicNameValue = new byte[buf.readUnsignedShort()];
            buf.readBytes(topicNameValue, 0, topicNameValue.length);
            String topicName = new String(topicNameValue, "UTF-8");
            if (!StringVerifier.verify(topicName))
                throw new MalformedMessageException(
                        "Publish-topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");

            Integer packetID = null;
            if (qos != QoS.AT_MOST_ONCE) {
                packetID = buf.readUnsignedShort();
                if (packetID < 0 || packetID > 65535)
                    throw new MalformedMessageException("Invalid PUBLISH packetID encoding");
            }

            ByteBuf data = Unpooled.buffer(buf.readableBytes());
            data.writeBytes(buf);
            header = new Publish(packetID, new Topic(new Text(topicName), qos), data, retain, dup);
            break;

        case PUBACK:
            header = new Puback(buf.readUnsignedShort());
            break;

        case PUBREC:
            header = new Pubrec(buf.readUnsignedShort());
            break;

        case PUBREL:
            header = new Pubrel(buf.readUnsignedShort());
            break;

        case PUBCOMP:
            header = new Pubcomp(buf.readUnsignedShort());
            break;

        case SUBSCRIBE:
            Integer subID = buf.readUnsignedShort();
            List<Topic> subscriptions = new ArrayList<>();
            while (buf.isReadable()) {
                byte[] value = new byte[buf.readUnsignedShort()];
                buf.readBytes(value, 0, value.length);
                QoS requestedQos = QoS.valueOf(buf.readByte());
                if (requestedQos == null)
                    throw new MalformedMessageException(
                            "Subscribe qos must be in range from 0 to 2: " + requestedQos);
                String topic = new String(value, "UTF-8");
                if (!StringVerifier.verify(topic))
                    throw new MalformedMessageException(
                            "Subscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
                Topic subscription = new Topic(new Text(topic), requestedQos);
                subscriptions.add(subscription);
            }
            if (subscriptions.isEmpty())
                throw new MalformedMessageException("Subscribe with 0 topics");

            header = new Subscribe(subID, subscriptions.toArray(new Topic[subscriptions.size()]));
            break;

        case SUBACK:
            Integer subackID = buf.readUnsignedShort();
            List<SubackCode> subackCodes = new ArrayList<>();
            while (buf.isReadable()) {
                short subackByte = buf.readUnsignedByte();
                SubackCode subackCode = SubackCode.valueOf(subackByte);
                if (subackCode == null)
                    throw new MalformedMessageException("Invalid suback code: " + subackByte);
                subackCodes.add(subackCode);
            }
            if (subackCodes.isEmpty())
                throw new MalformedMessageException("Suback with 0 return-codes");

            header = new Suback(subackID, subackCodes);
            break;

        case UNSUBSCRIBE:
            Integer unsubID = buf.readUnsignedShort();
            List<Text> unsubscribeTopics = new ArrayList<>();
            while (buf.isReadable()) {
                byte[] value = new byte[buf.readUnsignedShort()];
                buf.readBytes(value, 0, value.length);
                String topic = new String(value, "UTF-8");
                if (!StringVerifier.verify(topic))
                    throw new MalformedMessageException(
                            "Unsubscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF");
                unsubscribeTopics.add(new Text(topic));
            }
            if (unsubscribeTopics.isEmpty())
                throw new MalformedMessageException("Unsubscribe with 0 topics");
            header = new Unsubscribe(unsubID, unsubscribeTopics.toArray(new Text[unsubscribeTopics.size()]));
            break;

        case UNSUBACK:
            header = new Unsuback(buf.readUnsignedShort());
            break;

        case PINGREQ:
            header = PINGREQ;
            break;
        case PINGRESP:
            header = PINGRESP;
            break;
        case DISCONNECT:
            header = DISCONNECT;
            break;

        default:
            throw new MalformedMessageException("Invalid header type: " + type);
        }

        if (buf.isReadable())
            throw new MalformedMessageException("unexpected bytes in content");

        if (length.getLength() != header.getLength())
            throw new MalformedMessageException(String.format("Invalid length. Encoded: %d, actual: %d",
                    length.getLength(), header.getLength()));

        return header;
    } catch (UnsupportedEncodingException e) {
        throw new MalformedMessageException("unsupported string encoding:" + e.getMessage());
    }
}

From source file:com.navercorp.nbasearc.gcp.RedisDecoder.java

License:Apache License

private boolean hasFrame(ByteBuf in) {
    if (in.isReadable() == false) {
        return false;
    }//from  ww  w.  java 2s .  co m

    lookasideBufferLength = Math.min(in.readableBytes(), lookasideBuffer.length);
    in.readBytes(lookasideBuffer, 0, lookasideBufferLength);
    lookasideBufferReaderIndex = 0;
    in.readerIndex(in.readerIndex() - lookasideBufferLength);

    byte b = lookasideBuffer[lookasideBufferReaderIndex++];
    in.skipBytes(1);
    if (b == MINUS_BYTE) {
        return processError(in);
    } else if (b == ASTERISK_BYTE) {
        return processMultiBulkReply(in);
    } else if (b == COLON_BYTE) {
        return processInteger(in);
    } else if (b == DOLLAR_BYTE) {
        return processBulkReply(in);
    } else if (b == PLUS_BYTE) {
        return processStatusCodeReply(in);
    } else {
        throw new JedisConnectionException("Unknown reply: " + (char) b);
    }
}